简单的C语言子进程/父进程程序意外终止

3
所以我一直在阅读StackOverflow上的帖子和fork手册,但我仍然无法理解我看到的行为,可能是因为我只寻找我想要的东西。
这是一个简单的程序,它接受文件名,生成子进程,在文件上运行stat(),然后循环中通过SIGUSR1或2将信号返回给父进程。父进程只想知道是1还是2…
但我得到的是"User defined signal 2",然后程序退出。但父进程在while循环中,不应该会持续执行吗?
总之,我真的希望有人能解释为什么我没有得到预期的输出,特别是循环反复询问文件名并每次生成一个子进程,而父进程要知道子进程通过kill()返回的信号是什么。
pid_t pid;

while(1) {
    if(pid == 0) // i am the child
    {
        FILE *fp = fopen(fname, "r");
        if(fp == NULL){
            printf("%d] Child cannot find [%s].", msg++, fname);
            fclose(fp);
        }
        else {
            stat(fname, &st);
            n = st.st_size;
            printf("%d] Child read %d chars.\n", msg++, n);
            if(n%2) kill(pid, SIGUSR1);
                else kill(pid, SIGUSR2);
        }

    }
    else // im the parent
    {
        if( signal(SIGUSR1,NULL) ) // Code never gets here because it ends
            printf("%s is odd\n", fname );

        if( signal(SIGUSR2, NULL) )
            printf("$s is even\n", fname );

        printf("%d] Enter filenames until you're happy. 'die' to end.\n", msg++);
        scanf("%s", fname);
        pid = fork();
    }

}
return 0;

因为父进程在子进程发送信号给父进程之前终止了。 - Grijesh Chauhan
为什么父级在 while 循环中会结束? - Aage Torleif
抱歉,我错了!你没有初始化 pid_t pid; - Grijesh Chauhan
即便如此,我应该有一个无限循环。主循环中只有一个返回。 - Aage Torleif
是的,但请阅读Sakthi的答案,您在子进程中缺少父进程的PID。 - Grijesh Chauhan
1个回答

4
在子进程中,pidfork会将子进程的pid返回给父进程,但子进程得到的是,您正在尝试杀死一个pid为0的进程,但init的pid是1,您可以使用getpid()获取当前childpid,然后尝试发送信号。
编辑: 此外,在循环第一次进入时,pid未初始化,这也可能导致未定义的行为。感谢@Giresh。

因为在 if pid == 0 中没有给 pid; 分配任何值,这是未定义的行为。请检查以下代码片段:pid_t pid; while(1) { if(pid == 0) ..... - Grijesh Chauhan
WOOW Sakthi,我简直不敢相信我花了2个小时来解决这个问题。谢谢你! - Aage Torleif
@GrijeshChauhan 感谢您提供的额外信息,已将其添加到答案中。 - Sakthi Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接