2011-06-10 86 views
4

我對下面複製粘貼的程序有疑問。我在這裏解釋我對程序的理解:在這個程序中,父母創建一個孩子並等待它完成。然後,孩子創建一個線程並等待它完成。因此,變量''在子進程中的值爲'5',在父進程中的值爲'0',因爲實際上有兩個副本變量''值'其中一個在父級和其他在子項中(因爲fork基本上是將父項的地址空間複製到子項)。然而,父母和孩子的變量''的地址都是相同的。我不明白如何。如果有人能解釋這種行爲,我將不勝感激。親子子線程程序的奇怪行爲

#include <stdio.h> 
#include <pthread.h> 


int value = 0; 
void *runner(void *param); 

int main() 
    { 
    int pid ; 
    pthread_t tid; 
    pthread_attr_t attr; 

    pid = fork(); 

    if(pid == 0) /* child */ 
     { 
     pthread_attr_init(&attr); 
     pthread_create(&tid, &attr, runner, NULL); 
     pthread_join(tid, NULL); 
     printf("CHILD: value = %d, address = %p\n", value, &value); 
     } 
    else if(pid > 0) /* Parent */ 
     { 
     wait(NULL); 
     printf("PARENT: value = %d, address = %p\n", value, &value); 
     } 
    } 

void *runner(void *param) 
    { 
    value = 5; 
    pthread_exit(0); 
    } 

回答

3

現代操作系統提供每個過程的虛擬地址空間,所以一致的地址並不意味着兩個變量被存儲在物理內存相同的目的地。

此外,大多數操作系統在分岔時使用寫入時複製技術。這意味着父進程的地址空間的一部分不會複製到子進程的地址空間,直到子進程嘗試更改它們。

+0

糾正我,如果我錯了。虛擬地址不應該是唯一的嗎? – 2011-06-10 13:56:14

+0

這可能意味着地址0xDEADBEEF將轉換爲任何兩個進程的不同內存位置。 – 2011-06-10 13:58:24

+0

這是否意味着程序以某種方式打印偏移量?然後將其轉換爲物理地址? – 2011-06-10 14:03:59

1

桌面CPU和許多嵌入式CPU有一些稱爲內存管理單元(MMU)的東西。 MMU從虛擬地址轉換爲物理地址,因此每個進程都在自己的虛擬地址空間上運行,與其他進程分開。

MMU允許操作系統使用一些重要的技術,如按需分頁,以及上述過程之間的分離。

fork()的高效實現需要使用MMU:正如您剛剛發現的,父進程和子進程使用相同的虛擬地址,但在不同的虛擬地址空間中,因此通常(忽略內存映射文件和共享內存)映射到不同的物理地址。