Linux 当已经在信号处理程序中接收到信号时会发生什么?

Linux 当已经在信号处理程序中接收到信号时会发生什么?,linux,signals,Linux,Signals,我有一个父进程产生几个子进程。我想通过注册一个SIGCHLD信号处理程序来了解任何子进程何时退出 问题是,当父进程已经在信号处理程序中时,如果接收到另一个SIGCHLD(或任何其他信号),会发生什么情况 我可以想到以下结果: 信号被忽略 信号已排队,并将在当前处理程序返回时立即处理 与主程序一样,当前处理程序也会被中断 哪一个是正确的?在您的具体示例中(接收到相同的信号),信号在信号处理程序完成后发送(因此,要点2是正确的)。但是,请注意,您可能会“丢失”信号 原因是当信号在其处理程序中时,

我有一个父进程产生几个子进程。我想通过注册一个
SIGCHLD
信号处理程序来了解任何子进程何时退出

问题是,当父进程已经在信号处理程序中时,如果接收到另一个
SIGCHLD
(或任何其他信号),会发生什么情况

我可以想到以下结果:

  • 信号被忽略
  • 信号已排队,并将在当前处理程序返回时立即处理
  • 与主程序一样,当前处理程序也会被中断
哪一个是正确的?

在您的具体示例中(接收到相同的信号),信号在信号处理程序完成后发送(因此,要点2是正确的)。但是,请注意,您可能会“丢失”信号

原因是当信号在其处理程序中时,它被阻塞。阻塞信号设置为挂起,但不排队。术语“挂起”表示操作系统记住有一个信号在下一次机会等待传递,“未排队”表示它通过在某处设置标志来实现这一点,但不是通过保留已到达信号的确切记录

因此,在处理程序中,您可能会收到2或3(或10)个以上的
SIGCHLD
,但只能看到一个(因此在某些情况下,项目符号1也可能是正确的)

请注意,可以传递给
sigaction
的几个标志可能会影响默认行为,例如
SA_NODEFER
(防止阻塞信号)和
SA_NOCLDWAIT
(在某些系统上可能根本不会生成信号)


当然,如果你收到不同类型的信号,不能保证它不会中断你的处理器。因此,最好不要使用非信号安全函数。

因此,如果我总结一下,在
SIGCHLD
的信号处理程序中,其他
SIGCHLD
信号要么丢失,要么在处理程序返回后传递。但是任何其他类型的信号都会中断信号处理程序本身?对于1和2是(在处理程序返回后最多发送1个额外信号)。对于3,它也是“是”,尽管带有“但是”。同步信号(例如,
SIGSEGV
)将直接中断处理程序,但异步信号当然仍遵循正常规则,即它们在未知但定义明确的时间传递,例如在内核/用户开关处,因此它们不会直接中断处理程序。但是,如果您给它们一个机会(所以只使用函数),它们很可能在处理程序运行时交付。这是一个好问题。