C语言 如果信号处理程序在处理时接收到另一个信号,它将如何工作?



我试着测试信号处理程序中到底发生了什么。

int num = 0;
void    handler(int signum, siginfo_t *sip, void *ptr)
{
sleep(1);
num ++;
write(1, "processs!n", 10);
}
int main(void)
{
int pid = getpid();
struct sigaction    act1;
printf("%dn", pid);
//act1.sa_flags = SA_NODEFER;
act1.sa_sigaction = &handler;
sigaction(SIGUSR1, &act1, NULL);
sigaction(SIGUSR2, &act1, NULL);
while (1)
{
sleep(1);
printf("%dn", num);
};
}

在另一个进程中,我发送了两个信号,结果是这样的:杀(pid, SIGUSR1);杀(pid, SIGUSR1);据我所知,信号处理程序阻塞了调用自己的信号.....阻塞信号在处理程序结束后被处理。我希望处理程序将被调用两次,全局变量num将为2;

但是它只被调用了一次并且num是1

然后我试着发送两个不同的信号,像这样:杀(pid, SIGUSR1);杀(pid, SIGUSR2);

据我所知,SIGUSR2将在处理程序仍处于睡眠状态时被处理,并且第一个处理程序将在这里退出,并且num ++将无法工作。它将在稍后调用的处理程序中只处理一次。

但是在这个试验中调用了两次处理程序并且num为2 ....

我对信号处理程序的想法是否有任何误解?我很困惑。

这是你的误解:

和第一个处理程序将在这里退出,num ++将无法工作。

当一个信号处理程序中断另一个信号处理程序时,一旦中断的信号处理程序结束,被中断的信号处理程序就从它离开的地方恢复。它不仅仅是提前结束。

顺便说一下,你的代码有很多问题:
  1. 因为你不使用SA_SIGINFO,你的handler应该只接受一个参数,应该在sa_handler而不是sa_sigaction
  2. 你没有初始化struct sigaction的大多数字段,所以当你调用sigaction时,可能会发生非常奇怪的事情。
  3. 你真的被限制在你被允许从信号处理程序内部做什么;特别是,不允许访问int类型的全局变量。修改numvolatile sig_atomic_t
  4. 你基本上不应该在循环之外使用write,因为部分写基本上是允许在任何时候发生的。

至于为什么发送SIGUSR1两次并不总是运行处理程序两次,那是因为非实时信号被允许合并,所以如果你的第二个kill发生在第一个信号处理程序开始运行之前,那么第二个有效地不会做任何事情。

相关内容

  • 没有找到相关文章

最新更新