首先來段代碼
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必須負責將虛擬地址轉換爲物理地址。
由圖可知,同一個變量,地址相同,其實是虛擬地址相同,內容是通過頁表映射到不同的物理地址上!