繁体   English   中英

叉程序给 <defunct> 一段时间后处理

[英]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进行编码,则应考虑使用QtPOCO之类的框架(均提供对过程的支持)。

您应该关心进程间的通信 (也许使用pipe(7) -s或socket(7) -s以及一些事件循环 ,请参见poll(2) ...)和同步问题。 也许看看MPI0mq

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

也许strace(1)可能有助于调试问题。

不要忘记检查每个 系统调用 请参阅syscalls(2)errno(3)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM