为什么这个叉子挂了?

时间:2017-01-31 11:55:12

标签: c unix fork

为什么程序不结束?孩子在打印出要打印的内容后挂起。如果父进程睡觉而不是孩子,它会起作用,但为什么呢?我也尝试在每个进程结束时调用exit,但结果相同。我是否总是要等孩子完成?

int main(){

    int pid = fork();

    char s[100] = "Hello";

    if(pid > 0){
        printf("FIRST PRINT IN PARENT: %s\n", s);
        strcat(s, " - PARENT");
        printf("SECOND PRINT IN PARENT: %s\n", s);
    }
    else if(pid == 0){
        printf("IMMEDIATELY IN CHILD: %s\n", s);
        sleep(2);
        printf("AFTER 2 SCONDS IN CHILD: %s\n", s);
    }
    return 0;
}

2 个答案:

答案 0 :(得分:1)

当父母退出时,它可能会向孩子发送信号(SIGHUP)。 如果确实如此,如果孩子没有发现这个信号,孩子就会死亡。

从历史上看,默认情况下,一个流程会在退出时向其发送SIGHUP个孩子。如今,许多Linux发行版默认不发送SIGHUP

我在RHEL上尝试了你的代码并且没有杀死子进程。 所以父母死了,控制权返回了shell。孩子继续并在2秒后打印出它的第二个输出。

如果孩子确实收到SIGHUP,它就不会挂起。它会死掉,最后的字符串永远不会被打印出来。

在Linux中,您可以通过SIGHUP系统调用打开prctl

#include <sys/prctl.h>
prctl(PR_SET_PDEATHSIG, SIGHUP);

相关问题:how-to-make-child-process-die-after-parent-exits

答案 1 :(得分:0)

一旦shell子进程(即代码中的父进程)退出,shell就会给你提示。然而, 它不知道你的代码开始的子进程。

您观察到的问题的根源是您的父进程难以为其子级等待。 在父进程中使用wait(2)系统调用,例如wait(0);

不等待子进程的一般风险是你可能最终得到zombie processes;相反,orphan processes(如果您的父流程首先退出)。