一段时间后,Fork程序会给出<defunct>进程

时间:2017-02-10 13:03:01

标签: c++ fork

我正在开发一个使用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天之后。

谢谢。

2 个答案:

答案 0 :(得分:2)

我认为你有两个问题:

首先wait可以返回由于子进程已经终止以外的原因(如果有的话,它会留下一个已经不存在的进程)。我认为你需要传入一个非空指针,并检查返回的等待状态。如果合适,只减少数字。

其次numforks没有(有效地)限制子进程的总数。如果父进程启动两个进程,它们将继续继承0和1的numforks。然后每个子进程将启动500和499个子进程。

我认为您exit(0)之后需要break(或time_consuming_process())。

答案 1 :(得分:1)

(我假设你在Linux或其他一些POSIX系统上运行,如MacOSX)

谨防orphan processes

阅读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进行编码,则应考虑使用QtPOCO等框架(两者都提供对进程的支持)。

你应该关心inter-process communication(可能是pipe(7) - s或socket(7) - s和一些event loop,请参阅poll(2) ...)和{ {3}}问题。也许请查看synchronizationMPI

(您可能需要阅读更多内容)

或许0mq可能有助于调试您的问题。

不要忘记检查每个 strace(1)。见system call&amp; syscalls(2)