我是C程序员,第一次了解fork()
,exec()
和wait()
。我也是一个标准C程序的白板,它将在Linux上运行,可能需要很多子进程。我无法衡量的是......有多少子进程太多,一个父进行生成然后等待?
假设我的代码如下所示:
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 越大,父母仍然 fork()的可能性越大,而儿童则是分裂或变成僵尸或其他什么。
所以这个实现对我来说似乎有问题。据我了解,父母一次只能等待()一个孩子?如果 LARGENUMBER 很大,并且运行 status [0] = fork(); 和等待(状态[0])之间的时间差; 是实质性的?如果孩子跑了,变成了僵尸,并且在那段时间以某种方式被操作系统终止了怎么办?那么父母会永远等待(状态[0])吗?
在上面的示例中,必须有一些标准或指南来确定 LARGENUMBER 的大小。或者我的方法都错了?
#define LARGENUMBER 1
#define LARGENUMBER 10
#define LARGENUMBER 100
#define LARGENUMBER 1000
#define LARGENUMBER ???
我想玩这个,但我的本能是在将开发时间投入到可能会或可能不会变得不可行的程序之前征求意见。任何建议/经验都表示赞赏。
答案 0 :(得分:2)
如果您阅读documentation of wait
,就会知道
如果在调用wait()之前状态信息可用,则立即返回。
这意味着,如果孩子已经终止,wait()
将立即返回。
在您为子进程调用wait
¹或程序退出之前,操作系统不会从进程表中删除信息:
如果父进程终止而不等待其所有子进程终止,则将为剩余的子进程分配与依赖于实现的系统进程相对应的新父进程ID。
当然你仍然无法产生无限量的孩子,有关详细信息,请参阅Maximum number of children processes on Linux(就Linux而言,其他操作系统会施加其他限制)。
答案 1 :(得分:1)
我会尽力解释。
首先是一个不好的例子:你fork()
一个子进程,然后在分支另一个子进程之前等待它完成。这会导致多处理程度,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
}
应该怎么做? 在这种方法中,首先创建两个子进程,然后等待。提高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); }
注意:
即使在执行第二次等待之前父母正在等待,孩子仍然在运行,而不是等待执行或生成。
在您的情况下,您正在进行第二种方法,首先分叉所有进程并保存fork
的返回值,然后等待。
父母一次只能等待一个孩子?
父母可以一次一个地等待所有孩子!,他们是否已经完成并成为zombie process
或仍在运行。有关详细说明,请查看here。
父母在变得不可行之前可以产生多少子进程?
它可能依赖于操作系统,但一种可接受的方法是将给定进程的时间分为2,一半用于子进程,一半用于父进程。 因此,流程不会耗尽系统并通过创建子流程来欺骗,这些流程的运行速度将超过操作系统想要的父流程。