父進程
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).