2016-04-17 9 views
0

私は最近、Linux上で信号処理を行っており、信号処理に関するすべての概念を読んでいます。私の頭をかしめる問題の1つは、プロセスがブロックされていない間にsigtimedwait()のセットのシグナルが配信されない理由です。次のように私のコードは次のとおりです。 -sigtimedwait()の "set"パラメータの信号が届かない

#include <signal.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
#include <errno.h> 
void sighandler1(int sig) 
{ 
     printf("SIGINT caught\n"); 
} 
void sighandler2(int sig) 
{ 
     printf("SIGTSTP caught\n"); 
} 
void sighandler3(int sig) 
{ 
     printf("SIGALRM caught\n"); 
} 

int main() 
{ 

    sigset_t s1,s2; 

    struct sigaction act1,act2,act3; 

    int ret; 

    sigemptyset(&s1);// The bit-mask s1 is cleared 
    sigaddset(&s1,SIGINT);//Add SIGINT to the bit-mask s1 

    sigemptyset(&s2);// The bit-mask s2 is cleared 
    sigaddset(&s2,SIGALRM);//Add SIGALRM to the bit-mask s2 

    sigprocmask(SIG_BLOCK,&s2,NULL);//Signal(s) in s2 blocked 

    act1.sa_handler = sighandler1; //function pointer pointing to the signal handler 
    act1.sa_flags = 0;   

    sigaction(SIGINT,&act1,NULL); // installing the action 
           // for SIGINT 

    act2.sa_handler = sighandler2; //function pointer pointing to another signal handler 
    act2.sa_flags = 0;   // no flags 


    sigaction(SIGTSTP,&act2,NULL); // installing the action 
           // for SIGTSTP 
    act3.sa_handler = sighandler3; //function pointer pointing to another signal handler 
    act3.sa_flags = 0;   // no flags 


    sigaction(SIGALRM,&act3,NULL); // installing the action for SIGALRM 

    sigprocmask(SIG_SETMASK,&s1,NULL); //Signals in s1 blocked and other signals unblocked 
    printf("sigprocmask() called with SIG_SETMASK on s1,which contains SIGINT\n"); 
    printf("Blocked on sigtimedwait() with s1\n"); 
    if(sigtimedwait(&s1,NULL,NULL) < 0) 
     { 
       if(errno == EINTR) 
       printf("Some other signal caught\n"); 
     } 
    printf("This is a process. You can pass signal to it\n"); 

    while(1); 

} 

が質問をより明確にするために、私は、「設定」をパラメータとして「S1」と、上記のコードでsigtimedwait呼ばれています。このセットはシグナルSIGINTのみを含んでいます。マニュアルページにあるように、sigtimedwait()はそのセット内のシグナルの1つが配送されるまでプロセスをブロックします。私はその声明で大丈夫です。しかし、プロセスをブロック解除するためにSIGINTを渡すと、SIGINTハンドラが呼び出されないのはなぜですか?一方、セットに含まれていないSIGALRMまたはSIGTSTPを渡すと、EINTRが期待通りに返され、シグナルハンドラも呼び出されます。

シナリオを観察したい人は、上記のコードを実行してからSIGINTを渡すことができます。彼らは、ハンドラが呼び出されることなくプロセスがブロックされていないことを観察します。ハンドラが呼び出されないのはなぜですか?マニュアルページの一部を間違って解釈していますか?sigtimedwait() ??

+0

誰もこれに見ていただけますか?前もって感謝します。 –

答えて

0

sigtimedwaitではなく、シグナルハンドラが捕まるの、信号の値を返すようだ:

switch(sigtimedwait(&s1,NULL,NULL)) 
{ 
    default: 
     printf ("Some other signal???"); 
     break; 
    case SIGINT: 
     printf ("We got SIGINT\n"); 
     break; 
    case -1: 
     perror ("sigtimedwait"); 
     break; 
} 
+0

マニュアルページを見ると、次のようになります。 sigwaitinfo()は、保留中のシグナルのセットからシグナルを取り除き、シグナル番号をその関数の結果として返します。 info引数がNULLでない場合、それが指すバッファは、シグナルに関する情報を含むsiginfo_t型の構造体を返すために使用されます(sigaction(2)を参照)。 –

+0

はその後、何人-ページで説明の非常に最初の行に記載された次の文について - セットで 信号の一方が配信されるまで *て、sigwaitinfo()は、呼び出しスレッドの実行を一時停止* それがありません。信号が配信されなければならないと言う。しかし、私は、セット内のシグナルは配信されないが、セット内にないシグナル*は、ハンドラが呼び出されて配信されることを確認します。 –

+0

sigprocmask()呼び出しでSIGINTをブロックするのは、他のシグナルが通過できる理由です(sigtimedwaitが-1を返し、errnoをEINTRに設定する)。 sigtimedwaitの後、SIGINTはまだブロックされ、受信できません。言葉を渡すと、それはもはやカーネル待ち行列にないことを意味する。 sigtimedwaitはこの場合の信号の受信側です。 –

関連する問題