SIGUSR1终止了这个过程,虽然我阻止了它

时间:2016-02-16 11:42:15

标签: c linux

我有一个创建2个子进程的程序,因此,子进程1向子进程2发送SIGINT,子进程2处理SIGINT(SIGINT的处理程序阻塞SIGUSR1),在SIGINT之后,子进程1将SIGUSR1发送给子进程2。 我不知道为什么SIGUSR1终止子2.SIGUSR1在发送SIGINT时被阻止。

#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>

sigset_t base_mask, waiting_mask;

void handler(int signum)
{
  signal(SIGINT, handler);
  sigemptyset (&base_mask);
  sigaddset (&base_mask, SIGUSR1);
  /* Block user interrupts while doing other processing. */
  if(sigprocmask (SIG_BLOCK, &base_mask, NULL) != 0)
    printf("cannot block\n");
  else
    printf("SIGUSR1 blocked\n");
  if(sigismember(&base_mask, SIGUSR1))
    printf("sigusr1 in mask\n");
}

int main()
{
 if(fork())
  {
    if(fork())
    {
      printf("parent out\n");
    }
    else//child 2
    {
      printf("i am sib 2 with pid = %d\n", getpid());
      signal(SIGINT, handler);
      pause();
      printf("before sleep\n");
      sleep(10);
      printf("after sleep\n");
      /* After a while, check to see whether any signals are pending. */
      sigpending (&waiting_mask);
      if (sigismember (&waiting_mask, SIGUSR1))
        printf("/* SIGUSR1 pending. */\n");
      sleep(2);
      printf("2 out\n");
    }
  }
  else//child 1
 {
    printf("i am sib 1 with pid = %d\n", getpid());
    sleep(2);
    printf("SIGINT to %d\n", getpid() + 1);
    if(kill(getpid() + 1, SIGINT))
      printf("Signal cannot be sent\n");
    sleep(4);
    if(kill(getpid() + 1, SIGUSR1))
      printf("Signal 2 cannot be sent\n");
    else
      printf("SIGUSR1 sent to %d\n", getpid() + 1);
    sleep(4);
  }
  return 0;
}

输出:

parent out,
i am sib 1 with pid = 2525,
i am sib 2 with pid = 2526,
SIGINT to 2526,
SIGUSR1 blocked,
sigusr1 in mask,
before sleep,
SIGUSR1 sent to 2526

1 个答案:

答案 0 :(得分:1)

问题是:你在信号处理程序中阻止信号:

void handler(int signum) {
  ...
  if(sigprocmask (SIG_BLOCK, &base_mask, NULL) != 0)
    printf("cannot block\n");
  else
    printf("SIGUSR1 blocked\n");
  if(sigismember(&base_mask, SIGUSR1))
    printf("sigusr1 in mask\n");
}

但是从信号处理程序返回后,阻塞信号掩码恢复到处理程序进入时的值!因此,调用sigprocmask()仅对当前处理程序调用期间阻塞的信号有影响。你必须在信号处理程序之外调用它。