[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 系統管理 > 其它 > 正文
要怎樣才能避免在內存中留下zombie processes?
Steve Hayman (2001-04-19 11:33:05)
 很不幸地,對死掉的子 process 應有的行為特性並沒有辦法做一般化,因 
 為這些特定/特定的機制會隨 Unix 的種類不同而有所差異。 

 首先,在各種 Unix 上面您都必需使用 wait() 來處理子 process。也就是 
 說,我還沒看過有一種 Unix 會自動把結束的子 process 幹掉,即使您不告 
 訴它該怎做。 

 其次,在某些從 SysV 衍生的系統當中,如果您執行了 signal(SIGCHLD, 
 SIG_IGN)",(嗯,事實上應該是SIGCLD 而非SIGCHLD,但大多數新出 
 爐的 SysV 系統都會在表頭檔當中加上 #define SIGCHLD SIGCLD),那 
 子 processes 都會自動被清除得乾乾淨淨,您什事都不用做。看看這個 
 方式是否可行的最佳做法就是自己在機器上試試看。如果您想試寫出具可 
 攜性的程式碼,那依賴這種特殊處理方式可能不是好主意。不幸的是,在 
 POSIX 並不允許您這樣做;把 SIGCHLD 的行匭隕璩?nbsp;SIG_IGN 在 
 POSIX 當中並沒有定義,所以如果您要讓您的程式合乎 POSIX 的要求 
 時,您就不可以這樣做。 

 那怎樣才算是 POSIX 的做法呢?如同前面所述,您必需設定一個 signal 
 的處理函數,然讓它去 wait。在 POSIX 當中 signal 處理函數是經由 
 sigaction 設定,由您只對終止的子 process 感興趣,而不是那些 stopped 
 的子 process,所以可以在 sa_flags 當中加上 SA_NOCLDSTOP。如果要 
 wait 子 process 而本身不因此被擋 (block),可以使用 waitpid()。第一 
 個參數必需是 -1 (代表 wait 任何 pid),第三個參數必需是 WNOHANG,這是 
 最具可攜性的做法,也是可能會成為未來最具可攜性的寫法。 

 如果您的系統不支援 POSIX,那就有很多做法了。最簡單的方式就是先試 
 試signal(SIGCHLD, SIG_IGN) 是否可行,可以的話那就好了。如果 
 SIG_IGN 無法用來強制自動收拾殘骸,那您就要自己寫一個 signal 處理 
 函數來收拾殘骸了。要寫出一個適用每一種 Unix 的 singal 處理函數來 
 做這件事是不容易的事,因為有下列不一致的地方: 
 
 在一些 Unix 中,一個或一個以上的子 process 死時,會呼叫 SIGCHLD 的 
 signal 處理函數。也就是說,如果你的 signal 處理函數只有一個 wait() 
 時,並不會把所有的子 process 都收拾乾淨。不過還好,我相信這類的 
 Unix 都會有 wait3() 或 waitpid(),這兩者都有可在 option 參數中使用 
 WNOHNAG 可用來檢查是否有子 process 尚待收拾。所以在一個有 
 wait3()/waitpid() 的系統中,你可以一再重復使用 wait3()/waitpid() 
 以確定所有的子 process 都已收拾乾淨W詈檬怯?nbsp;waitpid() 因為 
 它在 POSIX 標準中。 

 在一些 SysV-derived 的系統中,再 SIGCHLD 的 signal 處理函數結束, 
 若還有子 process 等待清除,還是會產生 SIGCHLD signal。 因此,在大部 
 份的 SysV 系統中,在 signal 處理函數裡可以假設要處理的 signal 只有一 
 個, 
(http://www.fanqiang.com)
    進入【UNIX論壇

相關文章

======
 

★  樊強制作 歡迎分享  ★