waitpid()和fork()来限制子进程的数量

时间:2012-09-25 21:46:03

标签: c++ c concurrency

我的程序应该将子进程数限制为3.

使用下面的代码,waitpid会停止我的父进程,因此我无法在第一个进程后创建更多子进程。如果我不使用waitpid,那么我不知道子进程何时退出以减少活动进程的数量。

int numProcs = 0;
while(1==1) {
    /* 
     * inserts code that waits for incoming input 
     */
    numProcs++;
    pid = fork();
    if (pid == 0) {
        doStuff(); // may exit anytime, based on user input
    } else {
        if (numProcs > 3) {
            wait(&status);
            numProcs--;
        } else {
            waitpid(pid, &status, 0); // PROBLEM!
            numProcs--;
        }
    }
}

我一整天都在寻找这个问题。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

冒着明显的风险,你基本上只想放弃else子句。你正在寻找的逻辑是:

int max_active = 3; // or whatever
int number_active = 0;
bool done = false;

for (; !done; ++number_active) {
  // wait for something to do;
  GetSomeWork();
  // wait for something to finish, if necessary.
  for (; number_active >= max_active; --number_active)
    wait(&status);
  pid = fork();
  if (pid < 0)
    ReportErrorAndDie();
  if (pid == 0)
    DoTheWorkAndExit();
}

这实际上允许你在不重启的情况下更改max_active的值,这是围绕wait()调用的for循环的唯一理由。

显而易见的抱怨是我的版本中的number_active实际上并没有告诉你有多少进程是活动的,这是真的。它告诉你有多少进程你没有等待(),这意味着你可能会保留一些僵尸(但数量是有限的)。如果你经常运行或接近最大数量的任务,这没关系,除非你的最大值是巨大的,否则无论如何都是无关紧要的,因为唯一的设计要求是你不要使用超过最大任务数,因此您只需知道活动数不超过最大值。

如果这真的困扰你并且你想要清理任务,你可以把:

for (; waitpid(-1, &status, WNOHANG) > 0; --number_active) {}

在另一个for循环之前,它会在检查你是否需要阻止之前收获僵尸。 (如果根本没有进程,我不记得waitpid(-1,&amp; status WNOHANG)是否返回错误,但无论如何都没有意义继续循环错误。)

答案 1 :(得分:0)

您的代码有两个问题,但第二个问题被第一个掩盖了。

你当前的问题是waitpid(pid,&amp; status,0);将阻塞,直到具有指定pid的进程终止。您想将WNOHANG选项作为第三个参数添加到waitpid()调用中。这将确保呼叫不会阻止。

这将添加一个新问题:您必须自行检查是否有任何子进程已终止。您可以使用WIFEXITED宏执行此操作:

} else {
  waitpid (-1, &status, WNOHANG);
  if (WIFEXITED(status)) {
    numProcs--;
  }
}

第二个问题是您的原始代码只等待创建最新的pid。您应该等待-1,这是所有子进程。

相关问题