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

Posted

技术标签:

【中文标题】C Linux 编程 - 管道使子进程退出【英文标题】:C Linux programming - Pipe makes child process exit 【发布时间】:2018-03-09 10:54:26 【问题描述】:

我很难理解以下代码的行为。关闭文件描述符 p[0] 使程序退出(否则父进程将永远等待子进程)。这对我来说没有意义,因为子进程正在运行一个无限的while循环,为什么它们会因为管道的读取端关闭而退出?当然,您将无法写入管道,但 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);


【问题讨论】:

您确定您的应用程序可以在不添加我的答案中提到的头文件的情况下工作吗? () 【参考方案1】:

这是标准行为。您关闭了管道的读取端,因此无处可写。这会导致将SIGPIPE 信号发送到写入进程。

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

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

【讨论】:

哦,好吧。这就说得通了。我不得不承认,我有点跳过阅读教科书的信号部分。非常感谢您的回答:-)【参考方案2】:

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

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

【讨论】:

以上是关于C Linux 编程 - 管道使子进程退出的主要内容,如果未能解决你的问题,请参考以下文章

Android C++系列:Linux守护进程

linux c之通过管道实现兄弟间进程通信:

linux 进程间通信机制(IPC机制)- 管道

linux 编程问题:子进程1和2为啥也能对管道进行操作?

Linux系统编程(进程)———进程退出

Linux系统编程(进程)———进程退出