在变得不可行之前,parent 可以生成多少个 child 进程?

How many child processes can a parent spawn before becoming infeasible?

我是一名 C 程序员,第一次学习 fork()exec()wait()。我也在白板化一个标准 C 程序,它将 运行 on Linux 并且可能需要很多 child 进程。我无法衡量的是...有多少 child 个进程太多了,一个 parent 无法生成然后等待?

假设我的代码如下所示:

pid_t status[ LARGENUMBER ];
status[0] = fork();
if( status[0] == 0 )
{
    // I am the child
    exec("./newCode01.c");
}
status[1] = fork();
if( status[1] == 0 )
{
    // child
    exec("./newCode02.c");
}
...etc...
wait(status[0]);
wait(status[1]);
...and so on....

显然,LARGENUMBER 越大,parent 仍然 fork() ing while 的可能性就越大child人正在出现段错误或变成僵尸或其他什么。

所以这个实现对我来说似乎有问题。据我了解,parent 一次只能 wait() 一个 child?如果 LARGENUMBER 很大,并且 运行ning status[0] = fork(); 和 [=29 之间的时间差怎么办=]wait(status[0]); 是实质性的吗?如果 child 有 运行,变成僵尸,然后被 OS 以某种方式终止怎么办? parent 然后 wait(status[0]) 会永远吗?

在上面的例子中,必须有一些标准或准则来规定 LARGENUMBER 可以有多大。还是我的方法全错了?

#define LARGENUMBER 1
#define LARGENUMBER 10
#define LARGENUMBER 100
#define LARGENUMBER 1000
#define LARGENUMBER ???

我想玩这个,但我的直觉是在我将开发时间投入到一个程序之前征求意见,这个程序可能会或可能不会被证明是不可行的。任何 advice/experience 表示赞赏。

如果你读过documentation of wait,你就会知道

If status information is available prior to the call to wait(), return will be immediate.

也就是说,如果child已经终止,wait()会立即return。 在您为 child 进程调用 wait¹ 或您的程序退出之前,OS 不会从进程 table 中删除信息:

If a parent process terminates without waiting for all of its child processes to terminate, the remaining child processes will be assigned a new parent process ID corresponding to an implementation-dependent system process.

当然你仍然不能产生无限数量的children,更多细节见(就Linux而言,其他OS 将施加其他限制)。

¹: https://en.wikipedia.org/wiki/Zombie_process

我会尽力解释。

首先是一个不好的例子:你 fork() 一个 child 进程,然后等待它完成,然后再派生另一个 child 进程。这会破坏多处理程度,CPU 利用率低。

pid = fork();
if (pid == -1) { ... } // handle error
else if (pid == 0) {execv(...);} // child
else (pid > 0) {
    wait(NULL);  // parent
    pid = fork();
    if (pid == -1) { ... } // handle error
    else if (pid == 0) {execv(...);} // child
    else (pid > 0) {wait(NULL); } // parent
}

应该怎么做? 在这种方法中,您首先创建两个 child 进程,然后等待。提高 CPU 利用率和多处理程度。

pid1 = fork();
if (pid1 == -1) { ... } // handle error
if (pid1 == 0) {execv(...);}
pid2 = fork();
if (pid2 == -1) { ... } // handle error
if (pid2 == 0) {execv(...);}
if (pid1 > 0) {wait(NULL); }
if (pid2 > 0) {wait(NULL); }

注意:
尽管看起来 parent 在执行第二次等待之前正在等待,但 child 仍然是 运行ning 并且没有等待 execv 或正在生成。

在您的情况下,您正在执行第二种方法,首先分叉所有进程并保存 fork 的 return 值,然后等待。

the parent can only wait() for one child at a time?

parent 可以一次等待其所有 children!,无论他们已经完成并成为 zombie process 还是 运行ning。有关更多解释的详细信息,请查看 here.

How many child processes can a parent spawn before becoming infeasible?

它可能是 OS 相关的,但一种可接受的方法是将给予流程的时间分成 运行 2,一半用于 child 流程,另一半用于 parent 过程。 这样进程就不会耗尽系统并通过创建 child 进程来作弊,这将 运行 多于 OS 想要首先提供 parent 进程。