3

UnixネットワークプログラミングVol1第3版セクション5.10からの抜粋waitおよびwaitpid関数

#include    "unp.h"    
void
sig_chld(int signo)
{
    pid_t   pid;
    int     stat;    
    while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
        printf("child %d terminated\n", pid);
    }
    return;
}

...
// in server code
Signal(SIGCHLD, sig_chld); // used to prevent any zombies from being left around
...

..
// in client code
The client establishes five connection with the server and then immediately exit
...

参照waitpid

戻り値

waitpid():成功すると、状態が変化した子のプロセスIDを返します。WNOHANGが指定され、pidで指定された1つ以上の子が存在するが、まだ状態が変更されていない場合は、0が返されます。エラーの場合、-1が返されます。

上記のドキュメントに基づいて、現時点で子プロセスが終了していない場合にwaitpid戻ります。0私が正しく理解していれば、これにより関数がステートメントsig_chldから外れます。while

質問>したがって、このシグナルハンドラーが、終了したすべての子プロセスが確実に収集されることをどのように保証できますか?

4

1 に答える 1

8
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
        printf("child %d terminated\n", pid);

処理する子がなければ、シグナル ハンドラーには参加しません。ループは、ハンドラー自体にいる間に、2 番目または 3 番目の子が、キューに入れられない SIGCHLD の送信を変更または終了した可能性があるためです。したがって、ループは実際に、死んだ可能性のある子を見逃すのを防ぎます。0 を返すか、-1 (ECHILD) でエラーになり、その時点でリープする子がもうない場合に発生します。

于 2012-07-04T04:59:16.160 に答える