vfork()函式

道亦無名發表於2015-12-14

Linux通過系統呼叫和fork()的功能相同,除了不拷貝父程式的頁表項。子程式作為父程式的一個單獨的執行緒在它的地址空間裡執行,父程式被阻塞,直到子程式退出或執行exec()。子程式不能向地址空間寫入。在過去的3BSD時期,這個優化是很有意義的,那時並未使用寫時拷貝也來實現fork()。現在由於在執行fork()是引入了寫時拷貝頁表項了。如果Linux將來fork()有了寫拷貝頁表項,那麼vfork()就徹底沒用了。另外由於vfork語意非常微妙( 試想,如果exec()呼叫失敗會發生什麼?),所以最好讓他逐漸淡出。完全可以把vfork()實現成一個普普通通的fork()-----實際上,Linux2.2以前都是這麼做的。

vfork()系統呼叫的實現是通過向clone()系統呼叫傳遞一個特殊標誌來進行的。

  • 在呼叫copy_process()時,task_struct的vfork_done成員被設定為NULL。
  • 在執行do_fork()時,如果給定特別標誌,則vfork_done會指向一個特殊地址。
  • 子程式開始執行後,父程式不是馬上恢復執行,而是一直等待,直到子程式通過vfork_done指標指向它傳送訊號。
  • 在呼叫mm_release()時,該函式用於程式退出記憶體地址空間,並且檢查vfork_done是否為空,如果不為空,則會向父程式傳送訊號。
  • 回到do_fork(),父程式醒來並返回。
         如果一切執行順利,子程式在新的地址空間裡執行而父程式也恢復了在原地址空間的執行。這樣的實現,開銷確實降低了,不過他的設計並不是優良的。

相關文章