天天看點

UNIX之fork與vfork函數一、fork函數二、vfork函數

一、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。

UNIX之fork與vfork函數一、fork函數二、vfork函數

經過GCC之後,

UNIX之fork與vfork函數一、fork函數二、vfork函數

可以看出子程序的變量值改變,子程序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環境進階程式設計》第三版。