在apue这本书中,介绍了早期System V不可靠信号中SIGCLD的经典语义。如在RH7.2上编译并运行该程序则一切正常(不会出现重复打印"SIGCLD received"),

因为:
1)现今的Unices系统(包括Linux)都提供了可靠的信号机制.
2)Linux(RH7.2,kernel 2.4.7)上对SIGCLD的处理是: #define SIGCLD SIGCHLD.
btw: 现在的程序大都使用SIGCHLD(POSIX也是采用的该信号),而不用SIGCLD.

早期System V信号的一个问题是:捕捉到一个信号后,系统将对该信号的处理设为默认.因此很多的signal handler都这样写:
sig_xxx()
{
signal(SIGXXX, sig_xxx); /* 为捕捉下一个该信号 */
...
}
即便这样,如果在执行这句signal前又有一个SIGXXX产生,那么系统仍会按默认处理(i.e., 忽略该信号, 或终止该进程, etc.),有可能造成信号丢失. APUE还介绍了另一个问题(请参考section 10.4)

http://www.unixresources.net/linux/clf/program/archive/00/00/27/46/274615.html

 

APUE上SIGCLD语义写的有点不清楚,到底我们的系统是如何来处理SIGCLD信号呢?
    1.SIG_DFL :默认的处理方式是不理会这个信号,但是也不会丢弃子进行状态,所以如果不用wait,waitpid 对其子进行进行状态信息回收,会产生僵尸进程。
    2.SIG_IGN :忽略的处理方式,这个方式和默认的忽略是不一样的语意,暂且我们把忽略定义为SIG_IGN,在这种方式下,子进程状态信息会被丢弃,也就是自动回收了,所以不会产生僵尸进程,但是问题也就来了,wait,waitpid却无法捕捉到子进程状态信息了,如果你随后调用了wait,那么会阻塞到所有的子进程结束,并返回错误ECHILD,也就是没有子进程等待。
   3.自定义处理方式:SIGCLD会立即检查是否有子进程准好被等待,这便是SIGCLD最大漏洞了,一旦在信号处理函数中加入了信号处理方式重建的步骤,那么每次设置SIGCLD处理方式时,都会去检查是否有信号到来,如果此时信号的确到来了,先是调用自定义信号处理函数,然后是调用信号处理方式重建函数,在重建配置的时候,会去检查信号是否到来,此时信号未被处理,会再次触发自定义信号处理函数,一直循环。所以在处理SIGCLD时,应该先wait处理掉了信号信息后,再进行信号处理方式重建signal。

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐