2011-12-07 18 views
1

を再インストールします。私を混乱させるハンドラに2つの部分がありSIGCHLDハンドラIは次のようにSIGCHLDハンドラのいくつかの例を参照してください

void child()                             
{                              
    wait(0);                           
    signal(SIGCHLD, child);  
} 
void server_main() 
{ 
    ... 
    signal(SIGCHLD, child); 
    ... 
    for(;;;) { 
     ... 
     switch(fork()) { 
     ... 
     } 
    } 

: 1)。 SIGCHLDは、子プロセスが終了するか停止すると捕捉されます。それでは、なぜハンドラの中で待たなければならないのですか?信号はすでに到着しています。 2)。 SIGCHLDハンドラを再インストールする必要がある理由シグナルコールがハンドラを一度インストールするのではないのですか?

ありがとうございます!

答えて

2
  1. 子プロセスが終了すると、SIGCHLDが起動します。 。しかし、プロセステーブル( いわゆるゾンビプロセス)では、親プロセスが子プロセスの出口値 をフェッチすることができます。 wait()を呼び出すと、その子プロセスのプロセステーブル がクリアされます。
  2. n子プロセスのみを作成すると、すべてのn子プロセスが終了したときにシグナルハンドラがまだ存在している必要はありません。

signalの動作がUnixによって異なるため、代わりにsigactionを参照することをお勧めします。

+0

ありがとう、私は最初のポイントを参照してください。 2番目のシグナルハンドラは親の権利のためにインストールされていますか?複数の子プロセスが終了したときにシグナルハンドラが有効にならないのはなぜですか? – Oxdeadbeef

+0

説明をsarnoldで見てください。彼はそれをとてもうまく説明しました。 – halfdan

1

シグナルコールはハンドラを一度インストールしますか?

この動作に依存することはできません。おそらくシグナルハンドラがクリアされ、恐らくそれが持続するでしょう。これは、歴史的なシグナル処理に関する問題の一部です。私のシステムレポートのsignal(3) manページ:

When a signal occurs, and func points to a function, it is 
    implementation-defined whether the equivalent of a: 


      signal(sig, SIG_DFL); 

    is executed or the implementation prevents some 
    implementation-defined set of signals (at least including 
    sig) from occurring until the current signal handling has 
    completed. 

信頼性の低い信号がほぼSysVr4で導入sigaction(2)ベースの信号に置き換えるとPOSIX.1-2001で標準化されています:

struct sigaction { 
     void  (*sa_handler)(int); 
     void  (*sa_sigaction)(int, siginfo_t *, void *); 
     sigset_t sa_mask; 
     int  sa_flags; 
     void  (*sa_restorer)(void); 
    }; 

    int sigaction(int signum, const struct sigaction *act, 
       struct sigaction *oldact); 

これらは、悲しいことに、より複雑です書き込むことはできますが、コードを書いたら、ハンドラを再インストールする必要があるかどうか疑問に思う必要はなく、信号を処理している間に信号が2回目に到着する心配もありません。

関連する問題