首先来段代码
3#include<iostream>
4 #include<stdlib.h>
5 using namespace std;
6 int g_val=0;
7 int main()
8 {
9 pid_t id=fork();//父进程返回子进程的pid 子进程返回0
10 //两份进程共有一份代码,写实拷贝
11 if(id<0)
12 {
13 perror("fork()");
14 return 0;
15 }
16 else if(id==0)
17 {
18
19 //chlid
20 cout<<"child:"<<getpid()<<":"<<g_val<<":"<<&g_val<<endl;
21 }else{
22 //fathr
23
24 cout<<"parent:"<<getpid()<<":"<<g_val<<":"<<&g_val<<endl;
25 }
26 sleep(1);
27 return 0;
28 }
程序运行发现,输出出来的变量值和地址是一摸一样的,很好理解,因为子进程按照父进程为模板,父子并没有堆变量进程任何修改。
但是改一下代码
3#include<iostream>
4 #include<stdlib.h>
5 using namespace std;
6 int g_val=0;
7 int main()
8 {
9 pid_t id=fork();//父进程返回子进程的pid 子进程返回0
10 //两份进程共有一份代码,写实拷贝
11 if(id<0)
12 {
13 perror("fork()");
14 return 0;
15 }
16 else if(id==0)
17 {
18 int g_val=100;
19 //chlid
20 cout<<"child:"<<getpid()<<":"<<g_val<<":"<<&g_val<<endl;
21 }else{
22 //fathr
23 sleep(3);
24 cout<<"parent:"<<getpid()<<":"<<g_val<<":"<<&g_val<<endl;
25 }
26 sleep(1);
27 return 0;
28 }
以上代码子进程先跑完,也就是子进程先修改,完成之后,父进程再读取。但结果发现,父子进程,输出地址是一致的,但是变量内存不一样!
得出以下结论
- 变量内容不一样,所以父子进程输出的变量觉对不是一个变量
- 但是地址值是一样的,说明改地址绝对不是物理地址
- 在Linux地址下,这种地址叫做虚拟地址
- 我们在用c/c++语言所看到的地址,全部是虚拟地址!物理地址用户一概看不到,由OS统一管理,OS必须负责将虚拟地址转换为物理地址。
由图可知,同一个变量,地址相同,其实是虚拟地址相同,内容是通过页表映射到不同的物理地址上!