Linux進程地址空間

首先來段代碼

  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必須負責將虛擬地址轉換爲物理地址
    在這裏插入圖片描述由圖可知,同一個變量,地址相同,其實是虛擬地址相同,內容是通過頁表映射到不同的物理地址上!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章