双叉
在我的理解中,当进程想要派生后台进程时使用双叉,但是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秒钟?假设它在子进程退出之前退出,但根据this question子进程退出时它仍然会被收割,而父进程仍然不需要照顾它。
不能达到使用双叉的最初目标吗?
答案 0 :(得分:1)
该示例的目的是演示孙子的父级在其原始父级退出后成为进程1(init)。
为证明孙子的父级成为进程1,孙子调用getppid
并打印结果。
getppid
之前,则getppid
返回的不是pid 1。getppid
,则getppid
返回1。示例程序的目的是使#2发生。因此,需要确保原始父级在孙子级调用getppid
之前已经退出。它是通过在孙子中调用sleep(2)
来实现的。
在真实程序中,孙子不会sleep(2)
在那里。它将完成其工作。
由于这是一个玩具程序,所以孙子没有真正的工作要做。