父行程
UNIX
在UNIX里,除了行程0(即PID=0的交換行程,Swapper Process)以外的所有行程都是由其他行程使用系統呼叫fork建立的,這裡呼叫fork新增行程的行程即為父行程,而相對應的為其建立出的行程則為子行程,因而除了行程0以外的行程都只有一個父行程,但一個行程可以有多個子行程。
作業系統核心以行程識別碼(Process Identifier,即PID)來辨識行程。行程0是系統引導時建立的一個特殊行程,在其呼叫fork建立出一個子行程(即PID=1的行程1,又稱init)後,行程0就轉為交換行程(有時也被稱為空閒行程),而行程1(init行程)就是系統裡其他所有行程的祖先。
殭屍行程與孤兒行程
當一個子行程結束執行(一般是呼叫exit、執行時發生致命錯誤或收到終止訊號所導致)時,子行程的退出狀態(返回值)會回報給作業系統,系統則以SIGCHLD訊號將子行程被結束的事件告知父行程,此時子行程的過程控制段(PCB)仍駐留在主記憶體中。一般來說,收到SIGCHLD後,父行程會使用wait系統呼叫以取得子行程的退出狀態,然後核心就可以從主記憶體中釋放已結束的子行程的PCB;而如若父行程沒有這麼做的話,子行程的PCB就會一直駐留在主記憶體中,也即成為殭屍行程。
孤兒行程則是指父行程結束後仍在執行的子行程。在類UNIX系統中,孤兒行程一般會被init行程所「收養」,成為init的子行程。
為避免產生殭屍行程,實際應用中一般採取的方式是:
- 將父行程中對SIGCHLD訊號的處理常式設為SIG_IGN(忽略訊號);
- fork兩次並殺死一級子行程,令二級子行程成為孤兒行程而被init所「收養」、清理[1]。
Linux
在Linux核心中,行程和POSIX執行緒有著相當微小的區別,父行程的定義也與UNIX不盡相同。Linux有兩種父行程,分別稱為(形式)父行程與實際父行程,對於一個子行程來說,其父行程是在子行程結束時收取SIGCHLD訊號的行程,而實際父行程則是在多執行緒環境裡實際建立該子行程的行程。對於普通行程來說,父行程與實際父行程是同一個行程,但對於一個以行程形式存在的POSIX執行緒,父行程和實際父行程可能是不一樣的[2]。
參考資料
- ^ UNIX環境進階編程(Advanced Programming in the UNIX Environment),理察·史蒂文斯著,1992,ISBN 0-201-56317-7
- ^ 存档副本. [2011-11-26]. (原始內容存檔於2012-02-15).