2012-11-11 27 views
2

能有人請解釋以下程序的輸出。爲什麼我爲父母和孩子獲得相同的價值& a。有趣的父母和孩子的行爲,而這樣做叉

他們必須有不同的物理地址。假如我認爲我得到的虛擬地址,那麼他們怎麼能有相同的虛擬地址,因爲據我所知每個物理地址是唯一綁定到虛擬地址。

#include <stdio.h> 
#include <stdlib.h> 
int main(void) { 


    int pid=fork(); 
     int a=10; 
    if(pid==0) 
     { 
      a=a+5; 
      printf("%d %d\n",a,&a); 
     } 
     else 
     { 
      a=a-5; 
      printf("%d %d\n",a,&a); 
     } 
     return 0; 
} 

回答

10

子進程繼承父的虛擬地址空間,即使虛擬地址開始引用不同的物理地址,一旦孩子寫的頁面。這就是所謂的寫時複製(CoW)語義。

因此,在父&a被映射到一些物理地址。叉最初只是複製映射。然後,當進程寫入a,牛在和子進程踢,持有a物理頁被複制,虛擬地址映射更新爲指的副本和兩個進程都有自己的a副本,在相同的虛擬地址&a但在不同的物理地址。

每個物理地址是唯一綁定到虛擬地址

這不是真的。物理內存地址可能未映射,或者可能映射到一個或多個進程地址空間中的多個虛擬地址。

相反地,單個虛擬地址可以被映射到多個物理地址,只要在不同的進程的虛擬地址空間中存在這些虛擬地址。

[順便說一句,你不能可靠地打印內存地址%d(這恰好適用於32位x86)。改爲使用%p。而且,fork返回類型爲pid_t,不int]

+2

這是一個很好的答案,但我想你應該更清楚的是,虛擬:物理映射爲M:N - 不僅可以在同一個物理地址映射到多個虛擬地址(在一個或多個地址空間中),同一個虛擬地址可以映射到多個物理地址(當然每個地址空間不超過一個這樣的映射)。後者似乎是這裏的混亂點。 – zwol