我计划我的程序(这是我的第一个多线程的,所以我的天真),绕过一个循环,启动子进程,使得exec()被删除,并且一定要自己终止.
我不能使用等待(NULL),因为这使得并行计算不可能,因此我可能必须添加一个存储子代码的进程表,并且必须使用waitpid – 而不是非常地,但在一段时间过去之后 – 这是一个问题因为孩子的运行时间从几微秒到几分钟不等.如果我使用waitpid太早,我的父进程将被阻止,当我使用太晚了,我被僵尸淹没了,不能fork(),这不仅对我的进程不利,但可能会导致意想不到的问题,整体上系统.
我可能需要编写一些使用最大数量的孩子的逻辑,并且在达到该数字时阻止父代 – 但是这不应该是必需的,因为大多数孩子很快终止.我可以想到的另一个解决方案(创建一个双层父进程,产生并发的子进程,同时产生并等待孙子)对我来说太复杂了.可能我也可以找到一个非阻塞功能来检查孩子,只有在终止时才使用waitpid.
但是问题是:
为什么Linux保持僵尸呢?为什么要等我的孩子?这是为了执行父进程的纪律?在使用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
.您可以告诉waitpid不阻止(即,如果没有孩子可以立即返回)使用WNOHANG选项.而且,你不需要给waitpid一个PID.你可以指定-1,它会等待任何孩子.所以调用waitpid如下所示适合您的无阻塞约束和no-saving-pids约束:
waitpid( -1,&status,WNOHANG );
如果你真的不想正确地处理流程创建,那么你可以通过两次分享来获得init的收获责任,收获孩子,并给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,"Failed to fork :(" ); } exit( EXIT_SUCCESS ); } else if( temp_pid < 0 ){ error( EXIT_FAILURE,"Failed to fork :(" ); } else { wait( temp_pid ); }
在上述代码片段中,子进程分叉自己的子进程,立即存在,然后立即由父进程获取.孙子是孤儿,由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的两个代码?感兴趣的进程将如何检索第一个进程的退出代码?不要以为没有人关心退出代码.你认为是一个麻烦/ bug被广泛认为是有用和干净的.
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