我正在开发一个使用fork()
执行各种任务的程序。我正在启动程序,一切正常。我观察到经过一段时间(1天)后,我被<defunct>
个进程淹没,超过600 700 ...其中最大分叉被设置为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个叉子像线程池一样运行。
我真的不明白<defunct>
进程是什么,但我听说他们在SEG FAULT
这样的子进程中没有出现错误,而是父进程没有等待正确。
我想了解<defunct>
s,有什么想法可以解决这个问题吗?
我再说一遍,这发生在1-2天之后。
谢谢。
答案 0 :(得分:2)
我认为你有两个问题:
首先wait
可以返回由于子进程已经终止以外的原因(如果有的话,它会留下一个已经不存在的进程)。我认为你需要传入一个非空指针,并检查返回的等待状态。如果合适,只减少数字。
其次numforks
没有(有效地)限制子进程的总数。如果父进程启动两个进程,它们将继续继承0和1的numforks
。然后每个子进程将启动500和499个子进程。
我认为您exit(0)
之后需要break
(或time_consuming_process()
)。
答案 1 :(得分:1)
(我假设你在Linux或其他一些POSIX系统上运行,如MacOSX)
阅读Advanced Linux Programming,其中有几章与您的问题相关。
您最好保持 fork
的结果(在某些pid_t
变量或字段中),并处理所有三种情况(&gt; 0:{{1} }成功; == 0,在子进程中,&lt; 0:fork
失败!)。您应该恰当地致电waitpid(2)。在子流程中,拨打exit(3)(或execve(2) ...)
也许你应该处理fork
信号。仔细阅读 signal(7)。
(你没有展示足够的你的程序,需要整本书来解释所有这些)
根据经验,您不希望许多可运行的进程。在典型的笔记本电脑或台式计算机上,您不应该只有打开 runnable 进程。使用top(1)或ps(1)列出您的流程(尤其是了解您拥有的流程数量)。也许在您的终端中使用(至少在调试期间)bash SIGCHLD
builtin(它从您的shell中调用setrlimit(2)),例如作为ulimit
限制进程数(至50)。
如果使用正版C ++ 11进行编码,则应考虑使用Qt或POCO等框架(两者都提供对进程的支持)。
你应该关心inter-process communication(可能是pipe(7) - s或socket(7) - s和一些event loop,请参阅poll(2) ...)和{ {3}}问题。也许请查看synchronization或MPI。
(您可能需要阅读更多内容)
或许0mq可能有助于调试您的问题。
不要忘记检查每个 strace(1)。见system call&amp; syscalls(2)