行程與行程抽象

殭屍行程(zombie process)

想像一位房客已經退房、收拾好行李離開了,但他最後的帳單仍擱在櫃檯上沒人讀。人走了,可一小筆紀錄滯留著,直到有人去歸檔。殭屍行程就像那筆紀錄:一個已經結束執行、幾乎放掉一切的行程,但它的退出狀態還被保留著,等著父行程去讀。它死了,卻還沒被清走。

當行程終止時,作業系統釋放它的記憶體、關閉它的檔案,但必須保留一小塊殘餘——持有退出狀態的那筆行程表紀錄——直到父行程呼叫 wait 來收取。在這個過渡狀態裡,行程是個殭屍:它不用 CPU、幾乎不用記憶體,但仍佔著一個行程表位置,並在列表中顯示為「defunct」。父行程以 wait 回收它的那一刻,作業系統讀出狀態、移除紀錄,殭屍便永遠消失。

少數短暫的殭屍是完全正常的——每個終止的子行程在「退出」與「被回收」之間的那一瞬間都是殭屍。真正的問題是從不回收子行程的父行程:殭屍於是累積,而由於行程表是有限的,大量殭屍終將耗盡行程表位置、使新行程無法啟動。有兩點值得釐清:你無法殺掉殭屍(它已經死了,kill 信號毫無作用);清除它的方法是讓它的父行程回收它,或者,若父行程自己退出了,由 init 繼承並回收那些成了孤兒的殭屍。

一個程式 fork 許多子行程去做快速的工作,卻從不呼叫 wait。每個子行程結束後就成了標記為「defunct」的殭屍;幾小時後列表中塞滿殭屍,而它們一個也殺不掉。

忘了 wait 會留下殭屍;解法是回收,而非殺掉。

你殺不掉殭屍;它已經死了。它只有在父行程以 wait 回收它、或父行程退出後由 init 繼承並回收它時,才會被清除。

又称
defunct processzombie殭屍行程defunct 行程