无法关闭管道 : bad file descriptor

标签 c pipe fork

我有以下代码:

int fds[2];
if (pipe(fds) < 0) {
    fprintf(stderr, "ERROR, unable to open pipe: %s\n", strerror(errno));
}
if (fcntl(fds[0], F_SETFL, O_NONBLOCK) < 0) {
    fprintf(stderr, "ERROR, unable make read end non-blocking: %s\n", strerror(errno));
}

pid_t pid1 = fork();
if (pid1 == 0) {
    if (close(fds[0]) < 0) {
        fprintf(stderr, "ERROR, unable to close read end of pipe: %s\n", strerror(errno));
    }

    // go on to write something
}

pid_t pid2 = fork();
if (pid2 == 0) {
    if (close(fds[1]) < 0) {
        fprintf(stderr, "ERROR, unable to close write end of pipe: %s\n", strerror(errno));
    }

    // go on to read something
}

if (close(fds[1]) < 0) {
    fprintf(stderr, "ERROR, unable to close write end of pipe in main process: %s\n", strerror(errno));
}
if (close(fds[0]) < 0) {
    fprintf(stderr, "ERROR, unable to close read end of pipe in main process: %s\n", strerror(errno));
}

我收到错误消息“错误,无法关闭主进程中管道的写入端:错误的文件描述符”。我的印象是你应该在任何不使用该端的进程中关闭管道的每一端。主进程在这里不使用管道。它的存在只是为了让两个 child 可以交流。此外,对 close() 的任何其他调用都没有其他错误。我不明白为什么父进程不能只关闭管道的写端。

最佳答案

我认为发生的事情是当子进程退出 if 语句时,它正在生成一个子进程并试图关闭一个已经关闭的管道:

pid_t pid1 = fork();
if (pid1 == 0) {
    // child 1 comes here
    if (close(fds[0]) < 0) {
        fprintf(stderr, "ERROR, unable to close read end of pipe: %s\n", strerror(errno));
    }

    // go on to write something

    // << you were supposed to call exit here. Child 1 passes through.
}

pid_t pid2 = fork();
if (pid2 == 0) {
    // child 2 comes here first, but after that,
    // child 1 will respawn a new child (child 3). Child 3
    // closes a different pipe so no crash here.

    if (close(fds[1]) < 0) {
        fprintf(stderr, "ERROR, unable to close write end of pipe: %s\n", strerror(errno));
    }

    // go on to read something

    // Big problem: Child 2 and Child 3 will pass through here.
}

// The main thread, as well as children 1, 2 and 3 are all here now.
// if any 2 threads try to close this pipe, you will get an error:

if (close(fds[1]) < 0) {
    fprintf(stderr, "ERROR, unable to close write end of pipe in main process: %s\n", strerror(errno));
}

解决方案

在 if 语句末尾调用 exit 以防止子级退出 if 语句并继续关闭管道。

关于无法关闭管道 : bad file descriptor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29762181/

相关文章:

c - 如果 x <= y,只使用按位运算符创建一个返回 1 的函数

java - 使用 Amorino 从 Arduino 向 Android 发送和接收数据结构(反之亦然)

c - 管道导致进程卡住

c - 通过这些 fork() 调用创建了多少个进程?

c - 使用 ld 链接已编译的程序集和 C 文件

c - 为什么我的快速排序算法不适用于重复元素?

c - 如何杀死fork的 child ?

c - 如何 fork 一个 child 来替换已完成的 child ?

haskell - Haskell 中的管道字符串到 shell 命令

python - 如何包装用于自动化的 windows 交互式控制台程序