為什麼 vfork() 打算在子程序創建後立即呼叫 exec() 或 exit() 時使用?
作業系統概念和 APUE 說
使用vfork(),父程序掛起,子程序使用父程序的地址空間。因為 vfork() 不使用寫時複製,所以如果子程序更改了父地址空間的任何頁面,一旦父程序恢復,更改的頁面將對父程序可見。因此,必須謹慎使用vfork(),以確保子程序不會修改父程序的地址空間。
vfork() 旨在在子程序在創建後立即呼叫 exec() 或 exit() 時使用。
我該如何理解最後一句話?
vfork()
呼叫創建的子程序時exec()
,不會exec()
通過載入新程序來修改父程序的地址空間嗎?
vfork()
呼叫創建的子程序時,終止子程序時exit()
不exit()
修改父程序的地址空間嗎?我偏愛Linux。
謝謝。
vfork()
呼叫創建的子程序時exec()
,不會exec()
通過載入新程序來修改父程序的地址空間嗎?不,
exec()
為新程序提供新的地址空間;它不會修改父地址空間。例如,參見POSIX中函式的討論exec
和Linuxexecve()
聯機幫助頁。當vfork()創建的子程序呼叫exit()時,exit()在終止子程序時不會修改父程序的地址空間嗎?
普通
exit()
的可能——它執行由正在執行的程序(包括它的庫)安裝的退出鉤子。vfork()
更嚴格;因此,在 Linux 上,它要求使用_exit()
不呼叫 C 庫的清理函式的函式。
vfork()
事實證明很難做到正確;它已在目前版本的 POSIX 標準中被刪除,posix_spawn()
應改為使用。但是,除非您真的知道自己在做什麼,否則您不應該使用
vfork()
orposix_spawn()
; 堅持好老fork()
和exec()
。上面連結的 Linux 聯機幫助頁提供了更多上下文:
然而,在過去糟糕的日子裡,a
fork(2)
需要製作呼叫者數據空間的完整副本,這通常是不必要的,因為通常緊接著 anexec(3)
就完成了。因此,為了提高效率,BSD 引入了vfork()
系統呼叫,它並沒有完全複製父程序的地址空間,而是藉用了父程序的記憶體和控制執行緒,直到發生呼叫execve(2)
或退出。父程序在子程序使用其資源時被掛起。的使用vfork()
很棘手:例如,不修改父程序中的數據取決於知道哪些變數保存在寄存器中。