C Linux编程 - 管道使子进程退出

时间:2018-03-09 10:54:27

标签: c unix pipe

我很难理解以下代码的行为。关闭文件描述符p [0]会使程序退出(因为否则父进程将永远等待子进程)。它对我没有意义,因为子进程正在运行无限循环,为什么它们只是因为管道的读端被关闭而退出?当然,您无法写入管道但是while循环不依赖于父进程的读取端是否打开。我尝试删除子进程中的exit()函数,并且程序仍会退出,那么为什么子进程会在注意到读取结束时立即自行查找?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

main()
{
    int run=10, fd[2]; pipe(fd); srand(time(0)); char ch, x='x', o='o'; 

    if(!fork())
    {
        close(fd[0]);

        while(run)
        {
            sleep(1+rand()%6); write(fd[1],&x,1);
        }

        exit(0); //This exit doesn't happen
    }

    if(!fork())
    {
        close(fd[0]);

        while(run)
        {
            sleep(1+rand()%3); write(fd[1],&o,1);
        }

        exit(0); //This exit doesn't happen
    }

    close(fd[1]);
    while(run--)
    {
        read(fd[0],&ch,1);
        printf("%d %c\n",run,ch);
        sleep(1);
    }

    close(fd[0]); //closing this file descriptor results in that the program can exit
    wait(0);
    wait(0);
    exit(0);

}

2 个答案:

答案 0 :(得分:1)

这是标准行为。你关闭了管道的读端,所以没有地方可以写。这导致SIGPIPE信号被发送到写入过程。

SIGPIPE的默认行为是终止接收信号的进程。

如果您希望您的过程在信号中存活,您必须捕获或忽略它。然后,您必须检查write的结果,因为当管道读取结束时它将返回错误。

答案 1 :(得分:0)

你的问题不在于管道。您的代码中缺少两个头文件,并且在调用wait()函数时它会崩溃。在程序中添加以下两个头文件,它将解决您的问题。您的main函数声明也是旧的c类型声明,使其像void main()

<sys/types.h>
<sys/wait.h>