我正在用很多分叉编写一个小程序。第一个家长必须等待每一个孩子。对于只有一个子节点,这很容易,有子节点结束信号(SIGCLHD)。但如果我的第一个孩子比最后一个孩子早死了怎么办?我的主程序在everychildren结束前运行,我需要主程序等待children。
每个子程序都以另一个程序的执行结束,这解释了为什么我不能与信号量之类的东西同步。
// Working pretty good
execvp(
c->command_name, /* program to execute */
c->argv /* argv of program to exécuter */
);
这是我的"fork-structure":
main
|
|------
| |
| |
| |------
| | |
| EOE |
| |
| EOE
|
|
EOE
传奇:
- EOE表示"执行结束"
- line top-bot为时间轴
- 每到左边一个新的步骤都是一个新的子步骤。
- 每条竖线代表一条竖线的执行
谢谢!
在SIGCHLD处理程序中使用waitpid
来查找哪个子进程已经终止:
/* SIGCHLD handler. */
static void sigchld_hdl (int sig)
{
pid_t child_pid;
/* Wait for all dead processes.
* We use a non-blocking call to be sure this signal handler will not
* block if a child was cleaned up in another part of the program. */
while ((child_pid = waitpid(-1, NULL, WNOHANG)) > 0) {
// child_pid contains the terminated child process' pid
}
}
要了解更多细节和此片段所基于的sscce,请查看示例的源代码。
编辑:所以问题问的是如何不仅等待子进程,而且等待所有的后代进程。
在伪代码:int alive_descendants = 0;
sigchld_handler() {
decrement alive_descendants for each zombie;
}
int main() {
setup-sigchld-handler;
int fd[2];
if (pipe(fd)) { error }
to create a child:
write a single byte to fd[1]
fork off the child
in the child process:
close(fd[0]);
to create child:
write a single byte to fd[1]
fork off the child
...
in the root process:
close(fd[1]);
for each byte read from fd[0], increment alive_descendants
if alive_descendants == 0 and fd[0] is empty:
ascertain that all descendants have terminated
close(fd[0]);
}
你试过了吗
// for each child spawned:
children[i] = fork(); // children is an array of pid_t
if (children[i] == 0) {
execvp(
c->command_name, /* programme à exécuter */
c->argv /* argv du programme à exécuter */
);
// parent process keeps doing its thing, and then
for (i = 0; i < NUMBER_OF_CHILDREN; i++) {
waitpid(children[i], NULL, 0);
}