子進程
在計算機領域中,子進程為由另外一個進程(對應稱之為父進程)所創建的進程。子進程繼承了父進程的大部分屬性,例如文件描述符。
產生
在Unix中,子進程通常為系統調用fork
的產物。在此情況下,子進程一開始就是父進程的副本,而在這之後,根據具體需要,子進程可以藉助exec調用來鏈式加載另一程序。
與父進程的關係
一個進程可能下屬多個子進程,但最多只能有1個父進程,而若某一進程沒有父進程,則可知該進程很可能由內核直接生成。在Unix與類Unix系統中,進程ID為1的進程(即init進程)是在系統引導階段由內核直接創建的,且不會在系統運行過程中終止執行(可參見Linux啟動流程);而對於其他無父進程的進程,則可能是為在用戶空間完成各種後台任務而執行的。
當某一子進程結束、中斷或恢復執行時,內核會發送SIGCHLD信號予其父進程。在默認情況下,父進程會以SIG_IGN函數忽略之[1]。
「孤兒進程」與「殭屍進程」
在對應的父進程結束執行後,進程就會變成孤兒進程,但之後會立即由init進程「收養」為其子進程。
某一子進程終止執行後,若其父進程未提前調用wait
,則內核會持續保留子進程的退出狀態等信息,以使父進程可以wait
獲取之[2] 。而因為在這種情況下,子進程雖已終止,但仍在消耗系統資源,所以其亦稱殭屍進程。wait常於SIGCHLD信號的處理函數中調用。
解決與預防
在POSIX.1-2001標準規定中,父進程可將SIGCHLD的處理函數設為SIG_IGN(亦為默認設定),或為SIGCHLD設定SA_NOCLDWAIT標記,以使內核可以自動回收已終止的子進程的資源。自Linux 2.6與FreeBSD 5.0起,兩種內核皆支持了這兩種方式[3]。但是,在忽略SIGCHLD信號的問題上,由於System V與BSD由來已久的差異,若要回收派生出的子進程的資源,調用wait
仍是最便捷的方式[2][4]。
參見
參考資料
- ^ 單一UNIX®規範第7期,由國際開放標準組織發布 : overview of signals – 參考,
- ^ 2.0 2.1 單一UNIX®規範第7期,由國際開放標準組織發布 : wait for process to change state – 參考,
- ^ http://fuse4bsd.creo.hu/localcgi/maSA_NOCLDWAITSA_NOCLDWAITn-cgi.cgi?signal+3[永久失效連結]
- ^ 單一UNIX®規範第7期,由國際開放標準組織發布 : examine and change a signal action – 參考,
- ^ 單一UNIX®規範第7期,由國際開放標準組織發布 : print process trees – 參考,