關於 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 }
沒有留言:
張貼留言