![](/img/trans.png)
[英]fork 100 processes at same time and sometimes some processes become zombie
[英]Fork program gives <defunct> processes after some time
我正在开发一个使用fork()
执行各种任务的程序。 我正在启动程序,一切正常。 我观察到一段时间(1天)后,我被<defunct>
进程淹没了,超过600 700 ...其中最大forks设置为500。这是代码:
int numforks = 0;
int maxf = 100;
// READ FROM FILE ...
while (fgets(nutt,2048,fp))
{
fflush(stdout);
if (!(fork()))
{
some_time_intensive_function();
exit(0);
}
else
{
numforks++;
if (numforks >= maxf)
{
wait(NULL);
numforks--;
}
}
}
// DON'T EXIT PROGRAM TILL ALL FORKS ARE FINISHED
while(numforks>0)
{
wait(NULL);
numforks--;
}
// CLOSE READ FILE ...
该程序始终像线程池一样保留500个fork。
我不太了解<defunct>
进程是什么,但我听说它们不是子进程(如SEG FAULT
发生的错误,而是父进程未正确等待。
我想阅读<defunct>
,有什么办法解决吗?
我重复一遍,这种情况会在1-2天后出现。
谢谢。
我认为您有两个问题:
首先,由于子进程终止之外的其他原因, wait
可以返回(如果终止,则它将退出已失效的进程)。 我认为您需要传递一个非null的指针,并检查返回的等待状态。 仅在适当的时候才减少木叉。
其次, numforks
不会(有效地)限制子进程的总数。 如果父进程启动两个进程,它们将继续继承0和1的numforks
。然后,每个子进程将启动500和499个更多的子进程。
我认为您需要在time_consuming_process()
之后exit(0)
(或break
time_consuming_process()
。
(我假设您正在Linux或MacOSX等其他POSIX系统上运行)
提防孤立进程 。
阅读高级Linux编程 ,其中有几章与您的问题有关。
您最好保留 fork
的结果(在某些pid_t
变量或字段中),并处理所有三种情况(> 0: fork
成功; == 0,在子进程中,<0: fork
失败!)。 您可能应该适当地调用waitpid(2) 。 在子进程中,调用exit(3) (或execve(2) ...)是合理的
也许您应该处理SIGCHLD
信号。 仔细阅读signal(7) 。
(您的程序显示不够,需要一本书来解释所有这些内容)
根据经验,您不希望有许多可运行的进程。 在典型的便携式计算机或台式计算机上,您不应有超过十二个可运行的进程。 使用top(1)或ps(1)列出您的进程(特别是要了解您有多少个进程)。 也许在终端中使用(至少在调试过程中)bash ulimit
内置 (它从您的shell内部调用setrlimit(2) ),例如,作为ulimit -u 50
来限制进程数(至50)。
如果使用正版C ++ 11进行编码,则应考虑使用Qt或POCO之类的框架(均提供对过程的支持)。
您应该关心进程间的通信 (也许使用pipe(7) -s或socket(7) -s以及一些事件循环 ,请参见poll(2) ...)和同步问题。 也许看看MPI或0mq 。
(您可能需要阅读更多内容)
也许strace(1)可能有助于调试问题。
不要忘记检查每个 系统调用 。 请参阅syscalls(2)和errno(3) 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.