1. 程式人生 > >【Linux/OS/Network】fork函式和vfork函式的分析及區別

【Linux/OS/Network】fork函式和vfork函式的分析及區別

fork和vfork相關程式碼見:

fork函式

標頭檔案:#include《unistd.h》

函式原型:pid_t fork(void);

一個現有程序可以呼叫fork建立一個新程序。

返回值:子程序中返回0,父程序中返回子程序ID,出錯返回-1。如下

這裡寫圖片描述

將子程序ID返回給父程序的理由是:因為一個程序的子程序可以有多個,並且沒有一個函式使一個程序可以獲得其所有子程序的程序ID。fork使子程序得到返回值0的理由是:一個程序只會有一個父程序,所以子程序總是可以呼叫getppid以獲得其父程序的程序ID

子程序和父程序繼續執行fork呼叫之後的指令。子程序是父程序的副本。例如:子程序獲得父程序資料空間、堆和棧的副本。但是父子程序並不共享這些儲存空間部分,父子程序共享正文段(程式碼段)。由於在fork之後經常跟隨著exec(程式替換),所以現在的很多實現並不執行一個父程序的資料段、堆和棧的完全副本。作為替代,使用了寫時複製(Copy-On-Write,COW)技術,如果父子程序中的任一個試圖修改這些區域,則核心只為修改區域的那塊記憶體製作一個副本,通常是虛擬儲存系統中的一“頁”。

一般來說fork之後父程序和子程序的執行順序是不確定的,這取決於核心的排程演算法。fork的一個特性是父程序的所有開啟檔案描述符都被複制到子程序中。父子程序的每個相同的開啟描述符共享一個檔案表項。

  • 在fork之後處理的檔案描述符有兩種常見的情況:
    1、父程序等待子程序完成。在這種情況下,父程序無需對其描述符做任何處理。當子程序終止後,子程序對檔案偏移量的修改已執行的更新。
    2、父子程序各自執行不同的程式段。這種情況下,在fork之後,父子程序各自關閉他們不需要使用的檔案描述符,這樣就不會干擾對方使用檔案描述符。這種方法在網路服務程序中經常使用。

  • fork有下面兩種用法:
    1、一個父程序希望複製自己,使父子程序同時執行不同的程式碼段。例如,父程序等待客戶端請求,生成子程序來處理請求。
    2、一個程序要執行一個不同的程式。例如子程序從fork返回後,呼叫exec函式。

  • fork呼叫失敗的原因:
    1、系統中有太多的程序
    2、實際使用者的程序數超過了限制

vfork函式

vfork用於建立一個新程序,而該新程序的目的是exec一個新程式。

  • vfork和fork的區別:
    1、vfork與fork都建立一個子程序,但它不將父程序的地址空間複製到子程序中,因為子程序會立即呼叫exec,於是不會存訪問該地址空間。在子程序呼叫exec或exit之前,它在父程序的空間中執行,也就是說會更改父程序的資料段、棧和堆。
    2、vfork保證子程序先執行,在它呼叫exec或exit之後父程序才可能被排程執行。

子程序呼叫exec或exit之前,它在父程序的空間中執行,如下圖:

這裡寫圖片描述