vfork() - Unix,Linux 系統呼叫 - 技術教學
Tutorials Point


  Unix 初學者指南
  Unix Shell 程式設計
  高階 Unix
  Unix 有用參考
  Unix 有用資源
  精選閱讀

版權所有 © 2014 tutorialspoint



  首頁     參考     討論論壇     關於 TP  

vfork() - Unix,Linux 系統呼叫


previous next AddThis Social Bookmark Button

廣告

名稱

vfork - 建立子程序並阻塞父程序

語法

#include <sys/types.h>
#include <unistd.h> 

pid_t vfork(void);

標準描述

(來自 SUSv2/POSIX 草案。)vfork() 函式與 fork() 的效果相同,除了 vfork() 建立的程序如果修改了除用於儲存 vfork() 返回值的 pid_t 型別變數之外的任何資料,或者從呼叫 vfork() 的函式中返回,或者在成功呼叫 _exit() 或 exec() 系列函式之一之前呼叫任何其他函式,則其行為未定義。

Linux 描述

vfork() 就像 fork(2) 一樣,建立呼叫程序的子程序。有關詳細資訊以及返回值和錯誤,請參閱 fork(2)。

vfork() 是 clone(2) 的特例。它用於建立新程序,而無需複製父程序的頁表。在效能敏感的應用程式中,它可能很有用,在這些應用程式中,將建立一個子程序,然後立即發出 execve()

vfork() 與 fork() 的區別在於,父程序會暫停,直到子程序呼叫 execve(2) 或 _exit(2)。子程序與父程序共享所有記憶體,包括堆疊,直到子程序發出 execve()。子程序不得從當前函式返回或呼叫 exit(),但可以呼叫 _exit()。

訊號處理程式是繼承的,但不是共享的。父程序的訊號在子程序釋放父程序的記憶體後到達。

歷史描述

在 Linux 下,fork() 是使用寫時複製頁面實現的,因此 fork() 產生的唯一開銷是複製父程序頁表所需的時間和記憶體,以及為子程序建立唯一的任務結構。但是,在過去,fork() 需要完全複製呼叫者的資料空間,這通常是不必要的,因為通常隨後會立即執行 exec()。因此,為了提高效率,BSD 引入了 vfork() 系統呼叫,它沒有完全複製父程序的地址空間,而是借用了父程序的記憶體和控制執行緒,直到呼叫 execve() 或退出發生。在子程序使用其資源時,父程序會被掛起。vfork() 的使用很棘手:例如,不修改父程序中的資料取決於知道哪些變數儲存在暫存器中。

錯誤

Linux 從過去重現這種幽靈,這相當不幸。BSD 手冊頁指出:“當實現適當的系統共享機制時,此係統呼叫將被消除。使用者不應依賴 vfork() 的記憶體共享語義,在這種情況下,它將與 fork() 同義。”

從形式上講,上面給出的標準描述不允許使用 vfork(),因為後續的 exec() 可能會失敗,然後會發生什麼是不確定的。

訊號處理的細節比較模糊,並且在不同的系統之間有所不同。BSD 手冊頁指出:“為了避免可能的死鎖情況,處於 vfork() 中間的子程序永遠不會收到 SIGTTOU 或 SIGTTIN 訊號;相反,允許輸出或 ioctl,輸入嘗試會導致檔案結束指示。”

目前(Linux 2.3.25),strace(1) 無法跟蹤 vfork(),需要核心補丁。

歷史

vfork() 系統調用出現在 3.0BSD 中。在 4.4BSD 中,它與 fork() 同義,但 NetBSD 再次引入了它,參見 http://www.netbsd.org/Documentation/kernel/vfork.html。在 Linux 中,它一直等價於 fork(),直到大約 2.2.0-pre6。從 2.2.0-pre9(在 i386 上,在其他架構上稍晚一些)開始,它是一個獨立的系統呼叫。支援已新增到 glibc 2.0.112 中。

符合標準

4.3BSD、POSIX.1-2001。標準對 vfork() 提出的要求弱於對 fork() 提出的要求,因此,其中兩者同義的實現符合標準。特別是,程式設計師不能依賴父程序在呼叫 execve() 或 _exit() 之前保持阻塞,也不能依賴任何關於共享記憶體的特定行為。

另請參閱



previous next Printer Friendly

廣告


  

廣告



廣告
© . All rights reserved.