0

私は最近、Linux でのシグナル処理に取り組んでおり、シグナル処理に関連するすべての概念を読みました。私の頭を悩ませている 1 つの質問は、プロセスのブロックが解除されている間、sigtimedwait() のセットのシグナルが配信されない理由です。私のコードは次のとおりです:-

#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);

}

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

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

4

1 に答える 1

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;
}
于 2016-04-22T09:02:12.087 に答える