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論壇】
|
|
| 相關文章 |
|
====== |
|
|
 |
★ 樊強制作 歡迎分享 ★ |