上篇文章:Linux基础4-进程4(环境变量,命令行参数详解)-优快云博客
本章重点:
1 重新理解c/c++地址空间
2 虚拟地址空间
目录
4.3 方便进程和编译器以统一的视角,来看待对应的代码和数据的各个区域
一. c/c++地址空间
地址空间布局图:
运行下列代码,进行观察
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int global_value = 100;
int main()
{
pid_t id = fork();
if(id < 0)
{
printf("fork error!\n");
return -1;
}
else if(id == 0) //子进程
{
int cnt = 0;
while(1)
{
printf("子进程,pid:%d ppid:%d | global_value:%d,&global_value: %p\n",getpid(),getppid(),global_value,&global_value);
sleep(1);
cnt++;
if(cnt == 10)
{
global_value = 1234;
printf("子进程已经修改了全局变量!\n");
}
}
}
else
{
//父进程
while(1)
{
printf("父进程,pid:%d ppid:%d | global_value:%d,&global_value: %p\n",getpid(),getppid(),global_value,&global_value);
sleep(2);
}
}
return 0;
}
我们定义一个全局变量,创建父子进程。让他们打印各自的全局变量值和其地址,然后让子进程修改其全局变量,观察父子进程各自的全局变量和其地址
运行结果如下
可以看到,子进程修改全局变量后,父子进程全局变量的地址相同但是值却不相同!这是为什么呢?
地址没变:说明这里使用的地址不是物理地址,我们C语言所使用的地址不是物理地址而是虚拟地址(逻辑地址)
我们所打印出来的地址空间排布,都是虚拟地址。所以上面的地址分布图是虚拟地址空间
OS访问变量时候,必须要通过虚拟地址找到其物理地址才能访问