进程概念--地址空间

研究背景:

  • kernel 2.6.32 

  • 32位


回顾程序地址空间 

进程概念--地址空间_第1张图片

 上段代码感受一下:

#include 
#include 
#include 
int g_val = 0;
int main()
{
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return 0;
    }
    else if (id == 0)
    { // child
        printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    else
    { // parent
        printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    sleep(1);
    return 0;
}

进程概念--地址空间_第2张图片

观察输出结果:发现父子进程的打印出的地址都是相同的 0x601058 ,这是因为父子并没有堆变量进行任何的修改。 下面稍微变更一下代码

#include 
#include 
#include 
int g_val = 0;
int main()
{
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return 0;
    }
    else if (id == 0)
    { // child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取
        g_val = 100;
        printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    else
    { // parent
        sleep(3);
        printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    sleep(1);
    return 0;
}

 

 发现父子进程时在打印时是同一块地址,但是g_val的值却不一样,则可以得出结论

  • 变量内容不一样,所以输出的值绝不是同一个变量
  • 但地址是一样的,所以说明这里的地址绝不是物理地址
  • 在Linux下我们叫这种地址为虚拟地址
  • 我们C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS进行管理

OS必须负责将虚拟地址转化成物理地址!!


进程地址空间

所以之前说的程序地址空间是不准确的,如图! 

进程概念--地址空间_第3张图片

上面的图就足矣说名问题,同一个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了不同的物理地址!

你可能感兴趣的:(算法,数据结构)