一、fork函數
1、每個程序都有一個非負整數表示的唯一程序ID,程序ID是可複用的;
- ID為0的程序通常是排程程序,被稱為交換程序(swapper),屬于核心的一部分,并不執行任何磁盤上的程式,也被成為系統程序;
- ID為1的程序通常是init程序,init通常讀取與系統有關的初始化檔案。init程序絕不會終止,他是一個普通的使用者程序,但是可以超級使用者特權運作。
- ID為2的是頁守護程序,負責支援虛拟存儲器系統的分頁操作。
2、一個現有的程序可以調用fork函數建立一個新程序。
#include <unistd.h>
pid_t fork(void);
//傳回值:子程序傳回0,父程序傳回子程序ID,若出錯,則傳回-1;
由fork建立的新程序被稱為子程序(child process),fork函數被調用一次,但傳回兩次。兩次傳回的差別是子程序的傳回值是0,而父程序的傳回值是建立子程序的程序ID。
- fork使子程序得到傳回值0,理由:
一個程序隻會有一個父程序,是以子程序總是可以調用getppid以獲得其父程序的程序ID(程序ID0總是由核心交換程序使用,是以一個子程序的程序ID不可能為0)。
- 子程序ID為什麼要傳回給父程序?
一個程序的子程序可以有多個,并且沒有一個函數使一個程序可以獲得其所有子程序的程序ID。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcFTUq1EMZRVT51keYhnRzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYvwFd4VGdvwlMvw1ayFWbyVGdhd3P3IDM1gjMxIjNxcDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
經過GCC之後,
可以看出子程序的變量值改變,子程序ID是9111,父程序ID為9110.
3、fork的兩種用法
(1)一個父程序希望複制自己,使父程序和子程序同時執行不同的代碼段。
比如在網絡服務程序中,父程序等待用戶端的服務請求,當這種請求到達時,父程序調用fork,使子程序處理此請求,父程序則繼續等待下一個服務請求。
(2)一個程序要執行不同的程式
shell中常見,子程序調用fork傳回後立即調用exec。
二、vfork函數
vfork函數用于建立一個新程序,而該新程序的目的是exec一個新程式。
vfork與fork都是建立一個子程序,但是它并不将父程序的位址空間完全複制到子程序中,因為子程序會立即調用exec或者exit,于是也就不會引用該位址空間,不過在子程序調用exec或exit之前,他在父程序的空間中運作。
vfork保證子程序先運作,在它調用exec或exit之後父程序才可能被排程運作,當子程序調用這兩個函數中的任意一個時,父程序會恢複運作。(如果在調用這兩個函數之前子程序依賴于父程序的進一步動作,則會導緻死鎖)。
參考《UNIX環境進階程式設計》第三版。