2011-02-02 47 views
8

嗨我創建了一個服務器程序,它在接受套接字連接後分叉一個新的進程。 在程序中定義了幾個靜態分配的全局變量。我的問題是這些靜態緩衝區後分配兩次?還是叉只重複堆和調用堆棧上的地址空間?C靜態變量和linux fork

回答

10

整個整個地址空間是重複的,包括所有全局變量和程序文本。

+0

我正在使用大約10MB的RAM,並且在撥號後沒有看到可用內存下降的數量?如果靜態分配在編譯時發生,那麼fork如何複製它? – 2011-02-02 20:10:39

2

fork()重複整個過程映像。所有的。因此,它們是否被分配兩次......不,它們被分配一次,每個可執行映像現在有兩個,而不是,如果您引用父級中的一個,它將不會保留與孩子,除非你使用共享內存。

static,該關鍵字是指本(來自ISO C99):

其標識符被聲明 與外部或內部的鍵,或者 與存儲類說明一個目的 靜態具有靜態存儲持續時間。 它的使用壽命是程序的整個執行 並且它的存儲值是 只有在 程序啓動之前初始化一次。

這基本上意味着您的緩衝區將作爲CRT啓動例程的一部分初始化一次,並且該空間在您退出時僅會消失。在這種情況下,當每個孩子退出時,該存儲消失。

6

整個地址空間在fork(2)期間是「重複的」。它通常與寫時複製完成,並且有關於共享程序文本和庫的更多詳細信息,但這與此處不相關。父進程和子進程都以自己的靜態數據副本結束。

1

Linux使用名爲copy-on-write的機制。這基本上意味着,只要變量不是修改父項,新進程就共享一個變量。但在變量被修改之前,它被複制並且新進程使用複製。這是出於性能原因而完成的,技術被稱爲延遲優化。所以你不應該擔心在一個進程中改變變量會改變另一個進程。