Exec
exec() 之後的 fork() 和 COW 行為
我們理解 fork 之後的 COW 行為(如這裡所描述的範例)如下:fork 為子程序創建父頁表的副本並將物理頁標記為只讀,因此如果兩個程序中的任何一個嘗試寫入它將觸發頁面錯誤並複制頁面。
子程序執行後會發生什麼?我們假設父程序可以再次寫入其頁面而不會觸發頁面錯誤,但事實證明很難找到有關如何實現的確切資訊。
歡迎任何指針(包括程式碼)!
當子程序執行時,它的所有目前頁面都被替換為一組全新的頁面,這些頁面對應於新的可執行映像(加上堆、堆棧等)。
現代作業系統通過維護父程序和子程序之間共享的物理頁面的引用計數來實現 CoW。如果頁面在父子之間共享,則引用計數將為 2。一旦子程序通過 exec,共享頁面的引用計數就會遞減(例如,它回到 1)因此父程序的任何寫操作沒有 CoW 也會成功。
為了您的娛樂,創建一個簡單的程序,它執行 fork,然後子程序休眠幾秒鐘,然後執行並執行。現在觀察
/proc/PID/smaps
fork 之前(當然只有父程序)、fork 之後但在 exec 之前和 exec 之後的兩個程序的內容。注意 Shared_XXX 頁面和相應的地址範圍。在程式碼方面,有一些簡單的 XV6 擴展支持寫時複製。一個簡單的Google搜尋可能就足夠了。另一個值得關注的地方可能是https://github.com/torvalds/linux/blob/master/kernel/fork.c。從分叉入口開始追踪它並玩得開心。
Fork 相當簡單,一旦你掌握了它,但記憶體管理可能是個婊子。參見“mm/memory.c”:“copy_page_range()”