关于system()实现中阻塞sigchld信号的问题(转帖)

这是一个网友的提问:
在 UNIX的system()函数实现过程中,要求在父进程中忽略掉SIGINT和SIGQUIT信号,但是要将SIGCHLD信号阻塞(在子进程中将 SIGINT和SIGQUIT信号设为默认,SIGCHLD信号解锁)。子进程执行完毕后,在父进程中调用waitpid(pid_t, &state, 0)。问题: 
1、若父进程已被waitpid阻塞,在子进程返回时,此时在父进程中SIGCHLD被阻塞(BLOCK),父进程收不到SIGCHLD信号,waitpid()函数能否正确返回,收集到子进程的信息? 
2、 waitpid若能正确完成,在以后父进程中,将SIGCHLD信号UNBLOCK,用sigprocmask()函数解锁,书上说,在 sigprocmask()函数返回以前,会将以前阻塞的信号发送给进程,父进程是否还能收到SIGCHLD信号?若能收到何必在开始时将SIGCHLD 进程阻塞。 
简单的对这个问题的解释是wait及其变体并不是通过sigchld信号来知道子进程状态的。
sigprocmask 阻塞的是有signal或sigaction设置的信号处理程序,即带有SIGCHLD_Handle()等处理函数。wait不是靠接收sigchld 信号获得子进程的退出状态的,如果进程中同时设置了signal和wait,则子进程退出后发出sigchld信号,交到signal的信号处理程序处 理,wait接收到子进程退出状态。
只是接收sigchld,而不调用wait还是会使子进程僵死的。一般的只有调用wait才能使子进程不成为僵死进程(除了2次fork 等或其他一些手段)。
概括下:waitpid不是依靠SIGCHLD是否到达来判断子进程是否退出,但是如果设置了SIGCHLD的处理函数,那么就需要等待SIGCHLD信号 的发生并完成信号处理函数,waitpid才能接收到子进程的退出状态。在APUE中的system()实现中阻塞了SIGCHLD信号,但是并没有设置 信号处理函数,所以waitpid在阻塞了SIGCHLD的情况下依然能正常返回,因为SIGCHLD在未设置信号处理函数的情况下不会影响到 waitpid的工作。至于为什么要阻塞SIGCHLD信号呢?那就是为了防止其他程序(main除了会调用system还会使用其他程序)设置了 SIGCHLD的信号处理函数,如果其他程序设置了SIGCHLD信号处理函数,在waitpid等待子程序的返回前,要去处理SIGCHLD信号处理程 序,如果阻塞了该信号,就不会去处理该信号处理程序,防止多余信息在system()中的出现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值