後臺面試經典問題-fork exec函式
Pid_t fork(void);
返回值:在子程序中返回0,在父程序中返回子程序id。出錯返回-1。
原因在於:任何子程序只有一個父程序,且子程序總是可以通過呼叫getppid取得父程序的程序ID。
而相反,父程序可以有許多子程序,而且無法獲取各個子程序的程序ID。
父程序中呼叫fork之前開啟的所有描述符在fork返回之後由子程序分享。可以看到網路伺服器利用了這個特性:父程序呼叫accept阻塞後呼叫fork,所接受的已連線套接字隨後與子程序共享。通常情況下,子程序繼續讀寫該套接字,而父程序關閉此套接字。
fork不帶引數,所有資源都通過複製資料結構進行復制。子程序獲得父程序資料空間,堆和棧的副本,注意這是副本也就是copy,與父程序無關(不共享)。子程序與父程序只共享正文段(程式碼段)。
一般而言,在fork之後是父程序先執行還是子程序先執行是不確定的。取決於核心的排程演算法。
子程序繼承父程序的如下特性:
1.開啟的檔案,或者是檔案偏移量
2.實際使用者ID,實際組ID,有效使用者ID,有效組ID
3.附屬組ID
4.程序組ID
5.會話ID
6.當前工作目錄
7.訊號遮蔽和安排
8.環境
9.儲存映像
不繼承(區別):
1.fork的返回值
2.程序ID
3.檔案鎖
…..
fork最主要的用法:
1.一個程序複製自己,使得能同時執行不同的程式碼段,這是網路伺服器的經典用法-父程序等待客戶端的服務請求(connect),當請求到達時,父程序呼叫fork讓子程序處理此請求,父程序繼續等待下一個客戶端連線請求。
2.一個程序要執行另一個不同的程式,這對於shell是常見的情況。子程序fork返回後立即呼叫exec。某些作業系統還會將fork和exec組合成一個操作:spawn。
函式exec
使用fork建立新的子程序後,子程序呼叫exec函式來執行另一個程式。當程式呼叫exec函式時,該程序執行的程式完全替換成為新程式,而新程式從main函式開始執行。exec並不建立新程序,所以前後程序ID不變。