Linux

為什麼 vfork() 打算在子程序創建後立即呼叫 exec() 或 exit() 時使用?

  • April 2, 2019

作業系統概念和 APUE 說

使用vfork(),父程序掛起,子程序使用父程序的地址空間。因為 vfork() 不使用寫時複製,所以如果子程序更改了父地址空間的任何頁面,一旦父程序恢復,更改的頁面將對父程序可見。因此,必須謹慎使用vfork(),以確保子程序不會修改父程序的地址空間。

vfork() 旨在在子程序在創建後立即呼叫 exec() 或 exit() 時使用。

我該如何理解最後一句話?

vfork()呼叫創建的子程序時exec(),不會exec()通過載入新程序來修改父程序的地址空間嗎?

vfork()呼叫創建的子程序時,終止子程序時exit()exit()修改父程序的地址空間嗎?

我偏愛Linux。

謝謝。

vfork()呼叫創建的子程序時exec(),不會exec()通過載入新程序來修改父程序的地址空間嗎?

不,exec()為新程序提供新的地址空間;它不會修改父地址空間。例如,參見POSIX中函式的討論execLinuxexecve()聯機幫助頁

當vfork()創建的子程序呼叫exit()時,exit()在終止子程序時不會修改父程序的地址空間嗎?

普通exit()的可能——它執行由正在執行的程序(包括它的庫)安裝的退出鉤子。vfork()更嚴格;因此,在 Linux 上,要求使用_exit()不呼叫 C 庫的清理函式的函式。

vfork()事實證明很難做到正確;它已在目前版本的 POSIX 標準中被刪除,posix_spawn()應改為使用。

但是,除非您真的知道自己在做什麼,否則您應該使用vfork()or posix_spawn(); 堅持好老fork()exec()

上面連結的 Linux 聯機幫助頁提供了更多上下文:

然而,在過去糟糕的日子裡,afork(2) 需要製作呼叫者數據空間的完整副本,這通常是不必要的,因為通常緊接著 anexec(3)就完成了。因此,為了提高效率,BSD 引入了vfork() 系統呼叫,它並沒有完全複製父程序的地址空間,而是藉用了父程序的記憶體和控制執行緒,直到發生呼叫execve(2)或退出。父程序在子程序使用其資源時被掛起。的使用 vfork()很棘手:例如,不修改父程序中的數據取決於知道哪些變數保存在寄存器中。

引用自:https://unix.stackexchange.com/questions/475609