为什么在父进程中先 fork() 然后 wait() ?
-
11-12-2019 - |
题
我知道 fork()、wait()、waitpid()、僵尸进程...我通过阅读 W.理查德·史蒂文斯,这是一本非常好的书。
如果我们不在父进程中调用 wait() ,子进程在终止后就会变成僵尸......这很糟糕!
如果我们在父进程中调用 wait() ,则父进程等待子进程终止,接收终止状态,然后继续。写?
我已经经历过许多调用 fork() 一次然后在父级中调用 wait() 的示例。
但是,如果父级要等待子级并在子级终止后继续,那么就不会发生实际的多任务处理(从技术上讲,是的,有两个进程。但逻辑上没有用)那我们为什么要在这里调用fork()呢?
我们可以先编写子代的代码,然后编写父代的代码,而不是 fork() 和 wait() 作为单个进程......这样不是更好吗?
谢谢!
解决方案
有时,即使父母立即停止,它也很有用。最常见的情况是当您正在为 system()调用,执行外部命令并等待它完成:您将执行 fork() + execve()。(虽然,在现代代码中,您应该考虑使用 posix_spawn()而不是此目的。) 不过, wait()不需要阻止。您可以使用 waitpid() with flag wnohang 以收集任何已完成的进程的退出代码或立即继续,如果仍在运行,请立即继续。
其他提示
您在其间编写的代码 fork()
和 waitpid()
与子叉子一起同时运行。
父级等待子级完成,通常只是为了获取从子级传递的数据并将其公开给父级。假设您运行一个主循环,其中任务作为“后台”运行。例如:
// a simple scheduler
while(1) {
if(done_task_1) {
// if done_task_1 is ever to change in the parent memory scope,
// parent must know the exit status of its child fork.
// otherwise there is no way to enter this if sentance, ever
collect_data_1();
run_task_1 = 0;
}
else if(run_task_1 == 1) {
// iterate instructions for a sec
posix_kill(pid_task_1, SIGCONT);
sleep(1);
posix_kill(pid_task_1, SIGSTOP);
}
if(done_task_2) {
collect_data_2();
run_task_2 = 0;
}
else if(run_task_2 == 1) {
// iterate instructions for a sec
posix_kill(pid_task_2, SIGCONT);
sleep(1);
posix_kill(pid_task_2, SIGSTOP);
}
if(run_task_1 == 0 && run_task_2 == 0) {
break;
}
}
不隶属于 StackOverflow