例如,在父进程中,我分叉子进程并等待子进程:
int main() {
setSignal(SIGCHLD, sigchld_handler)
while(1) {
// fork some child processes
myForkFunction()
waitpid(-1, &status, 0)
}
}
此外,我有一个SIGCHLD信号处理程序:
void
sigchld_handler(int sig) {
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
// Reap zombie processes
}
}
可以看出, waitpid()
出现在 main()
函数和 sigchld_handler()
函数中 . 我想知道 waitpid
是否可以被 SIGCHLD
打断 . 如果它可以被 SIGCHLD
中断,那么会发生什么?
有没有人对此有任何想法?
2 回答
waitpid()的POSIX规范部分说:
所引用的段落中的第三段似乎意味着你正在踩着薄冰 . 它没有提到“实现定义”或类似 - 未指定意味着标准没有说明将发生什么,您可能会或可能不会从特定于实现的文档中获取任何信息 .
POSIX规范中有很多(措辞非常密集)信息 . 还有一些例子和理由 - 提到sigwait()和sigwaitinfo() . 值得一读
waipid()
页面 . 您可能也应该阅读Signal concepts - 更密集的阅读 . (其中一天,我之前已经报道了 . )为什么使用
WUNTRACED
而不是0
或WNOHANG
?WUNTRACED
是一个非常专业的条件 - POSIX说:类似的评论适用于
WCONTINUED
. 当你需要它们时,这两个标志很有用,但你很少需要它们 .我建议您通常在
waitpid()
的第三个参数中使用0
或WNOHANG
.是的,从某种意义上说,只有其中一个能够成功完成特定的子进程;如果信号处理程序中断了
main
中的那个,那么在信号处理程序返回之后,子项将已经被收获并且main
中的调用将失败 .然而,据说,它是全局的,它必须知道您的程序可能已经完成的所有可能的子进程,并且有办法将这些结果传达给程序的适当部分 .
相反,通常最好通过管道进出子进程监视子进程的终止,并且只有
waitpid
才知道它被终止,或者从一个唯一的工作是等待子进程的线程执行阻塞waitpid
. .