unix - 在双叉中,为什么孙子退出之前不能退出?
问题描述
双叉
在我的理解中,当一个进程想要分叉一个后台进程时使用双叉,但是 1. 它不想等待它,并且 2. 后台进程应该在它退出后获得。
因此,双叉只需要父进程等待子进程,子进程在分叉孙子进程后立即退出,孙子进程作为后台进程负责真正的任务。
语境
根据 APUE 的这段摘录,孙子会休眠 2 秒以确保其父(子)在退出之前退出,这样它就会成为孤儿,而 init 会照顾它并在它退出时收割它。
#include "apue.h"
#include <sys/wait.h>
int
main(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* first child */
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid > 0)
exit(0); /* parent from second fork == first child */
/*
* We're the second child; our parent becomes init as soon
* as our real parent calls exit() in the statement above.
* Here's where we'd continue executing, knowing that when
* we're done, init will reap our status.
*/
sleep(2);
printf("second child, parent pid = %ld\n", (long)getppid());
exit(0);
}
if (waitpid(pid, NULL, 0) != pid) /* wait for first child */
err_sys("waitpid error");
/*
* We're the parent (the original process); we continue executing,
* knowing that we're not the parent of the second child.
*/
exit(0);
}
问题
为什么孙子进程需要休眠那 2 秒?假设它在子进程退出之前就退出了,按照这个问题,当子进程退出时它仍然会被收割,而父进程仍然不需要照顾它。
这不是实现了使用双叉的最初目标吗?
解决方案
该示例的目的是演示孙子的父级在其原始父级退出后成为进程 1 (init)。
为了证明孙子的父进程成为进程 1,孙子调用getppid
并打印结果。
- 如果孙子在其原始父级退出
getppid
之前调用,则getppid
返回不是 pid 1 的内容。 - 如果孙子在其原始父级退出
getppid
后getppid
调用,则返回 1。
示例程序的目的是使#2 发生。所以它需要确保在孙子调用之前原始父级已经退出getppid
。它通过调用sleep(2)
孙子来做到这一点。
在一个真正的程序中,孙子不会sleep(2)
在那里。它只会做它的工作。
由于这是一个玩具程序,孙子没有真正的工作要做。
推荐阅读
- r - 希望将 VIF 添加到 R 中的 export_summs 逻辑回归
- forms - 流星 - 如何编写引导模式模板以重新呈现 html 输入值,即使用户已输入它们
- flutter - 如何使桌子沿高度占据可用空间?
- python - 是否有用于查找向量中元素索引的 DolphinDB 函数?
- python - 无法加载动态库“libnvinfer.so.6”
- database - 如何在 dolphindb 中读取文本文件?
- java - 如何修复我的代码打印内存地址
- c# - 如何仅在按下按钮时将对象移动特定量?
- python - 获取外部导入的python内置函数代码
- model-view-controller - 使用 VS 的 MVC:为什么在使用 View() 时出现错误,但在使用 View(viewname) 时却没有?