在变得不可行之前,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 将施加其他限制)。
我会尽力解释。
首先是一个不好的例子:你 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 进程。
我是一名 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,更多细节见
我会尽力解释。
首先是一个不好的例子:你 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 进程。