gpt4 book ai didi

linux - 为什么我必须为子进程设置 `wait()`?

转载 作者:太空宇宙 更新时间:2023-11-04 11:56:22 25 4
gpt4 key购买 nike

尽管等待 linux 手册页 1很好地解释了您需要 wait() 来让子进程不变成僵尸,它根本没有说明原因。

我计划我的程序(这是我的第一个多线程程序,请原谅我的天真)围绕一个 for(;;)ever 循环启动子进程,该子进程获取 exec()ed 并肯定会自行终止。

我不能使用 wait(NULL) 因为这使得并行计算变得不可能,因此我可能必须添加一个存储子 pid 的进程表并且必须使用 waitpid - 不是立即,而是在一段时间后 - 这是一个问题,因为 child 的运行时间从几微秒到几分钟不等。如果我太早使用 waitpid ,我的父进程会被阻塞,当我太晚使用它时,我会被僵尸淹没,不能再 fork() 了,这不是只对我的过程不利,但可能会导致整个系统出现意外问题。

我可能必须编写一些逻辑来使用一些最大数量的子级并在达到该数量时阻止父级 - 但这应该没有必要,因为大多数子级很快就会终止。我能想到的另一个解决方案(创建一个两层父进程来生成并发子进程,这些子进程又同时为孙子进程生成和 wait)现在对我来说太复杂了。可能我还可以找到一个非阻塞函数来检查 child 并仅在他们终止时使用 waitpid

不过问题是:

为什么 Linux 会保留僵尸?为什么我必须等待我的 child ?这是为了对父进程实现纪律吗?在使用 Linux 的数十年中,我从未从僵尸进程中得到任何有用的东西,我不太了解僵尸进程作为“功能”的有用性。

如果答案是父进程需要找到一种方法来查明它们的子进程发生了什么,那么看在上帝的份上,没有理由仅仅因为存在僵尸进程就将僵尸进程视为正常进程并禁止创建非僵尸进程僵尸太多了。在我目前正在开发的系统上,我只能在一切都停止之前产生 400 到 500 个进程(这是一个维护不善的 CentOS 系统,运行在我能找到的最便宜的 VServer 上——但 400 个僵尸仍然少于几 kB 的信息)

最佳答案

I'll probably have to add a process table that stores the child pids and have to use waitpid - not immideately, but after some time has passed - which is a problem, because the running time of the children varies from few microseconds to several minutes. If I use waitpid too early, my parent process will get blocked

查看 documentation for waitpid .您可以使用 WNOHANG 选项告诉 waitpid 不阻塞(即,如果没有 child 要收割,则立即返回)。此外,您不需要为 waitpid 提供 PID。您可以指定 -1,它将等待任何 child 。因此,如下调用 waitpid 符合您的无阻塞约束和无保存 pids 约束:

waitpid( -1, &status, WNOHANG );

如果您真的不想正确处理进程创建,那么您可以通过 fork 两次、收割子进程并将exec 给孙子:

pid_t temp_pid, child_pid;
temp_pid = fork();
if( temp_pid == 0 ){
child_pid = fork();
if( child_pid == 0 ){
// exec()
error( EXIT_FAILURE, errno, "failed to exec :(" );
} else if( child_pid < 0 ){
error( EXIT_FAILURE, errno, "failed to fork :(" );
}
exit( EXIT_SUCCESS );
} else if( temp_pid < 0 ){
error( EXIT_FAILURE, errno, "failed to fork :(" );
} else {
wait( temp_pid );
}

在上面的代码片段中,子进程fork了自己的子进程,立即存在,然后立即被父进程收割。孙子是孤儿,由 init 收养,将自动收割。

Why does Linux keep zombies at all? Why do I have to wait for my children? Is this to enforce discipline on parent processes? In decades of using Linux I have never got anything useful out of zombie processes, I don't quite get the usefulness of zombies as a "feature". If the answer is that parent processes need to have a way to find out what happened to their children, then for god's sake there is no reason to count zombies as normal processes and forbid the creation of non-zombie processes just because there are too many zombies.

您还建议如何有效地检索进程的退出代码?问题是 PID <=> 退出代码(等)的映射必须是一对一的。如果内核在进程退出时立即释放进程的 PID,无论是否接收,然后新进程继承相同的 PID 并退出,您将如何处理为一个 PID 存储两个代码?感兴趣的进程将如何检索第一个进程的退出代码?不要仅仅因为您不关心退出代码就认为没有人关心退出代码。您认为是麻烦/错误的内容被广泛认为是有用且干净的。

On the system I'm currently developing for I can only spawn 400 to 500 processes before everything grinds to halt (it's a badly maintained CentOS system running on the cheapest VServer I could find - but still 400 zombies are less than a few kB of information)

将一个被广泛接受的内核行为作为替罪羊来表达对维护不善/廉价系统的明显不满似乎是不对的。

通常,您的最大进程数仅受内存限制。您可以通过以下方式查看您的限制:

cat /proc/sys/kernel/threads-max

关于linux - 为什么我必须为子进程设置 `wait()`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54225763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com