繁体   English   中英

waitpid()是Linux中的原子操作吗?

[英]Is waitpid() an atomic operation in Linux?

例如,在父进程中,我分叉子进程并等待子进程:

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()函数中。 我想知道SIGCHLD是否可以中断waitpid 如果它可以被SIGCHLD打断,那会发生什么?

有没有人对此有任何想法?

waitpid()的POSIX规范部分说明:

如果定义了_POSIX_REALTIME_SIGNALS,并且实现对SIGCHLD信号进行排队,那么如果由于子进程的状态可用而返回wait()waitpid() ,则应丢弃与子进程的进程ID关联的任何挂起的SIGCHLD信号。 任何其他待处理的SIGCHLD信号应保持未决状态。

否则,如果SIGCHLD被阻止,如果由于子进程的状态可用而返回wait()waitpid() ,则除非另一个子进程的状态可用,否则应清除任何未决的SIGCHLD信号。

对于所有其他条件,未指定在传送SIGCHLD信号时是否可以使用子状态。

所引用的段落中的第三段似乎意味着你正在踩着薄冰。 它没有提到“实现定义”或类似 - 未指定意味着标准没有说明将发生什么,您可能会或可能不会从特定于实现的文档中获取任何信息。

POSIX规范中有很多(措辞非常密集)信息。 还有一些例子和理由 - 提到了sigwait()sigwaitinfo() 值得阅读整个waipid()页面。 您也应该阅读有关Signal概念的内容 - 阅读更加密集。 (其中一天,我也会这样做 - 当我需要知道以前没有涉及的信号时。)


你为什么使用WUNTRACED而不是0WNOHANG WUNTRACED是一个非常专业的条件 - POSIX说:

WUNTRACED
pid指定的任何已停止的子进程的状态,以及自其停止后尚未报告其状态的状态,也应报告给请求进程。

类似的评论适用于WCONTINUED 当你需要它们时,这两个标志很有用,但你很少需要它们。

我建议你通常应该在waitpid()的第三个参数中使用0WNOHANG

是的,从某种意义上说,只有其中一个能够成功完成特定的子进程; 如果信号处理程序中断了main中的那个,那么在信号处理程序返回之后,子项将已经被收获并且main的调用将失败。

尽管如此,编写这样的代码是不好的做法。 应该有一个地方处理给定子进程的收获,通常信号处理程序是一个非常糟糕的选择,因为它是全局的,它必须知道您的程序可能已经完成的所有可能的子进程, 并且有办法将这些结果传达给程序的适当部分

相反,它是通常更好地监测通过子进程的终止poll上管/从孩子的过程,只有waitpid ,你知道后,它的终止,或进行阻止waitpid从一个线程,其唯一的工作就是等待孩子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM