我的程序应该将子进程数限制为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--;
}
}
}
我一整天都在寻找这个问题。有人可以帮忙吗?
答案 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,这是所有子进程。