SIGCLD语义-hds ams 2500用户手册
10.7 SIGCLD语义
S I G C L D和S I G C H L D这两个信号经常易于混淆。S I G C L D是系统V的一个信号名,其语义与名为S I G C H L D的B S D信号不同。P O S I X . 1则采用B S D的S I G C H L D信号。B S D的S I G C H L D信号的语义与其他信号的语义相类似。子进程状态改变后产生此信号,父进程需要调用一个wait函数以检测发生了什么。由于历史原因,系统V处理S I G C L D信号的方式不同于其他信号。如果用signal或sigset(设置信号配置的早期的与S R V 3兼容性函数)设置信号配置,则S V R 4继续了这一具有问题色彩的传统(即兼容性限制)。
对于S I G C L D早期的处理方式是:
-
如果进程特地指定对该信号的配置为S I G _ I G N,则调用进程的子进程将不产生僵死进程。注意,这与其默认动作(S I G _ D F L)忽略(见表10-1)不同。代之以,在子进程终止时,将其状态丢弃。如果调用进程最后调用一个wait函数,那么它将阻塞到所有子进程都终止,然后该wait会返回-1,其errno则设置为E C H I L D。(此信号的默认配置是忽略,但这不会造成上述语义。代之以我们必须特地指定其配置为S I G _ I G N。)P O S I X . 1并未说明在S I G C H L D被忽略时应产生的后果,所以这种行为是允许的。在4 . 3 + B S D中,如S I G C H L D被忽略,则允许产生僵死子进程。如果要避免僵死子进程,则必须等待子进程。在S V R 4中,如果调用signal或sigset将S I G C H L D的配置设置为忽略,则不会产生僵死子进程。使用S V R 4版的sigaction,则可设置S A _ N O C L D WAIT标志(见表10-5)以避免子进程僵死。
-
如果将S I G C L D的配置设置为捕捉,则内核立即检查是否有子进程准备好被等待,如果是这样,则调用S I G C L D处理程序。这一改变使得为此信号编写处理程序的方法发生了变化。实例10.4节曾提到进入信号处理程序后,首先要调用signal函数以再设置此信号处理程序。(在信号被复置为其默认值时,它可能被丢失,立即重新设置可以减少此窗口时间。)程序10-3显示了这一点,但此程序不能正常工作。如果在S V R 2下编译并运行此程序,则其输出是一行行地不断重复“SIGCLD received”。最后进程用完其栈空间并异常终止。此程序的问题是:在信号处理程序的开始处调用signal,按照上述改变,内核检查是否有需要等待的子进程(因为我们正在处理一个S I G C L D,所以确实有这种子进程),这导致了无限循环。
这些细节展示了在处理S I G C L D信号时,各个系统和标准之间的差异。如果你对进程信号有更多兴趣,可以参考进程信号详细解析或者Linux下的进程信号处理过程。他们会为你提供更全面的知识和实例。
这样看来,进程信号处理不仅仅是技术上的挑战,也是历史遗留问题的反映。你有没有想过,这些复杂的处理方式是如何影响系统性能和稳定性的呢?真是耐人寻味!