2011-09-06 43 views
2

我有幾個問題。任何輸入讚賞。謝謝。分叉子進程和C++對象

  • C++類生存分叉嗎?
  • 如果是這樣,它是如何實現的?
  • 指針會發生什麼?整個免費商店/堆被複制,所有的虛擬地址被保留?
  • 文件流發生了什麼?

回答

7

這裏是我的理解:

  • 待辦事項C++類活下來分叉?

是的。

  • 如果是這樣,它是如何實現的?

所有的內存被複制,所以你沒有任何問題。

  • 指針會發生什麼變化?整個免費商店/堆被複制,所有的虛擬地址被保留?

是的。

  • 文件流會怎樣?

這兩個進程保留所有打開的文件流的副本。 (默認情況下,有一些分支選項可以改變我的想法。) fork之後打開的流不共享。

3

這可以很容易地通過鍵入man fork回答:

  • 「孩子繼承打開文件描述符的父母的一套複印件。」

基本上,子進程將在完全相同的狀態父「父的整個虛擬地址空間中的孩子重複」(但看到一個男人頁這個極其過分簡單的陳述的例外清單)。

它是如何實現的?你想要什麼水平的細節?內存可能被實現爲寫時複製。但這不是你的擔心,子進程只是獲得整個內存的精確副本。

6

首先,要知道,這種行爲是非常平臺依賴。如果您除了好奇之外還有其他問題,我可以建議您重新考慮一下您的設計嗎?

這就是說,什麼是和不保留的叉由the POSIX standard指定。如何爲C++解釋這一點取決於你的C++(用戶空間)運行時是如何實現的。

文件流是一個有趣的案例。基礎文件描述符將被克隆,因此兩個進程都會有一個開放的描述符。但用戶空間緩衝區(如果有的話)最有可能得到重複。所以,舉例來說:

std::cout << "Hello!"; 
fork(); 
std::cout << std::endl; 

...有着相當不錯的打印Hello!兩次,僅僅是因爲緩衝區將得到(以及在這個過程中的地址空間中的一切)複製的機會。

總之,我會回答你的問題:

  • 這取決於類和你所說的「生存」的意思。

  • 它通過複製進程的整個虛擬地址空間來實現。

  • 指針保持它們的值,並且它們指向的內容被複制。 (這是「懶惰地」完成的;即作爲「寫入時複製」,因此它不像聽起來那樣低效)。

  • (re:文件流)參見上面。

+1

標籤確實會說「Linux」,所以平臺是相對特定的。好的例子與緩衝輸出。 –

+0

@Kerrek:除了新版本的Linux + g ++可以輕易改變細節。這實際上取決於運行時如何與內核交互。例如,你知道在fork()中futex發生了什麼嗎?我不... – Nemo

+0

呵呵 - 有人嗎? :-)引用如下:「父進程的整個虛擬地址空間在子進程中複製,包括互斥狀態,條件變量和其他pthreads對象的狀態」,但不知道是否包含futexes ... –