[英]What Happens When I Call fork() in Unix?
我試着看一下,但是在調用fork()之后,我正在努力理解父進程和子進程之間的關系。
它們是完全獨立的進程,只與id / parent id相關聯嗎? 或者他們共享記憶? 例如,每個進程的“代碼”部分是重復的,以便每個進程都有自己的相同副本,或者是以某種方式'共享'以便只存在一個?
我希望這是有道理的。
以完全披露的名義,這是“與家庭作業相關”; 雖然不是書中的直接問題,但我感覺它主要是學術性的,在實踐中,我可能不需要知道。
在整個過程中,整個內存都是重復的。
實際上,它使用“寫入時復制”系統。 第一次進程在fork()之后更改其內存時,會對已修改的頁面(通常為4kB)進行單獨的復制。
通常,流程的代碼段不會被修改,在這種情況下,它仍然是共享的。
從邏輯上講,fork會創建原始進程的相同副本,該副本在很大程度上獨立於原始進程。 出於性能原因,內存與copy-on-write語義共享,這意味着未修改的內存(如代碼)仍然是共享的。
文件描述符是重復的,因此分叉進程原則上可以代表父進程接管數據庫連接(或者如果程序員有點扭曲,它們甚至可以與數據庫聯合通信)。 更常見的是,這用於在進程之間設置管道,因此您可以編寫find -name '*.c' | xargs grep fork
find -name '*.c' | xargs grep fork
。
一堆其他的東西是共享的。 詳情請見此處 。
一個重要的遺漏是線程 - 子進程只繼承調用fork()
的線程。 這導致多線程程序中沒有問題,因為鎖定在父級中的互斥鎖等的狀態是特定於實現的(並且不要忘記malloc()
和printf()
內部使用鎖)。 fork()
返回后,子execve()
唯一安全的做法就是盡快調用execve()
,即使這樣你也必須對文件描述符保持謹慎。 在這里看到完整的恐怖故事。
編輯:錯別字HTH
是的,它們是獨立的過程,但有一些特殊的“屬性”。 其中之一是孩子與父母的關系。
但更重要的是以寫時復制(COW)方式共享內存頁:直到其中一個執行頁面上的寫入(全局變量或其他),內存頁面被共享。 執行寫入時,內核會創建該頁面的副本並映射到正確的地址。
通過在內核中將頁面標記為只讀並使用故障機制來完成COW魔術。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.