【问题标题】:C Linux programming - Pipe makes child process exitC Linux 编程 - 管道使子进程退出
【发布时间】: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);

}

【问题讨论】:

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

标签: c unix pipe


【解决方案1】:

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

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

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

【讨论】:

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

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

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

【讨论】:

    猜你喜欢
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    • 2020-12-07
    • 2020-12-29
    • 2017-05-08
    • 1970-01-01
    • 2014-03-07
    相关资源
    最近更新 更多