2012年5月2日 星期三

SIGCHLD 和 zombie

關於 zombie

  • zombie: ps 列的 status 為 Z, 表示 process 已結束, 資源也釋放了, 等待 parent process 呼叫 wait/waitpid 回收它的 exit status, 裡面包含 exit code
  • zombie 是無法被 kill 的, 僵屍無敵啊!!
  • zombie 會占據極小的系統資源, 如可 forked 的 process 數
  • 不註冊 SIGCHLD = 註冊 signal handler 為 SIG_IGR => OS 會在 child process 掛掉時直接回收, 不會變 zombie

關於 SIGCHLD 收發時機

  • 即使 child process 收到 SIGKILL, 它也不會當下就掛掉而讓 parent process 在當下收到 SIGCHLD。process 得等取得 CPU 時才會「處理」 SIGKILL 而掛掉。總之, 系統不保證 SIGCHLD 收到的時間
  • child process 正式掛掉後, 當 parent process 取得 CPU 時, 系統會盡快讓它收到 SIGCHLD。換句話說, 若 parent process 被停住的期間「收到」 SIGCHILD, resume 後會立即收到 SIGCHILD
  • SIGCHLD 如同其它 signal, 不會被 queued, 只有保證在有註冊 handler 的情況下, 至少會呼叫一次 handler (細節說明請查: signal mask/block )
  • 註冊 handler 前收到 SIGCHLD 的話, 不同系統作法不同, 可能會補送也可能不會補送

關於 handler

  • signal handler 會被繼承 (見 man fork 開頭), 所以若 A 有註冊 SIGCHLD 則 A 的 child process 和後續 grandchild process 都有 SIGCHLD handler。寫 handler 時要注意是否能沿用下去, 或是明確在每次 fork 後重設一次 child process 的 signal handler
  • 標準寫法如下, status 裡會記錄許多有用資訊, 見 man waitpid:
int status;
while ((pid=waitpid(-1, &status, WNOHANG)) > 0) {
    // Do something
}

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...