You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

管道(pipe)读写循环无法触发EOF问题排查

问题:pipe()读写循环无法触发EOF且输出异常

背景

此前发布过涉及fork()和pipe()的问题,后续发现问题仅出在pipe()上,因此移除了fork()相关代码。

问题描述

使用pipe()进行读写操作时,循环中始终无法触发EOF条件,且输出结果完全不符合预期。

简化代码

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

int fd[2];

int main() {
    if(pipe(fd) == 0) {
        printf("Pipe is Open\n");
    }
    for(int i = 0; i < 5; i++) {
        close(fd[1]);
        write(fd[0], &i, sizeof(int));
        close(fd[0]);
    }
    for(int i = 0; i < 5; i++) {
        int value;
        close(fd[0]);
        read(fd[1], &value, sizeof(int));
        close(fd[1]);
        printf("%d\n", value);
    }
    return 0;
}

程序输出

Pipe is Open
4
4
4
4
4

问题分析与解决

核心错误点

  • 管道读写端完全搞反:pipe()创建的管道中,fd[0]是读端,fd[1]是写端,代码里把两者的用途彻底弄反了。
  • 循环内反复关闭管道描述符:第一次循环就把读写端全部关闭,后续的write和read都是对已关闭的文件描述符操作,属于非法行为,程序行为完全未定义。
  • 未满足EOF触发条件:只有当管道的所有写端都关闭后,读端再读取才会触发EOF(read返回0),原代码逻辑完全不满足这个前提。

修正后的代码

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

int fd[2];

int main() {
    if(pipe(fd) == -1) { // 增加pipe创建失败的错误检查
        perror("pipe failed");
        exit(EXIT_FAILURE);
    }
    printf("Pipe is Open\n");

    // 统一完成所有写操作后关闭写端
    for(int i = 0; i < 5; i++) {
        write(fd[1], &i, sizeof(int)); // 使用正确的写端fd[1]
    }
    close(fd[1]);

    // 从读端读取直到触发EOF
    int value;
    ssize_t bytes_read;
    while((bytes_read = read(fd[0], &value, sizeof(int))) > 0) {
        printf("%d\n", value);
    }
    close(fd[0]);

    return 0;
}

修正说明

  1. 纠正管道读写端的使用,fd[1]负责写入数据,fd[0]负责读取数据。
  2. 避免循环内频繁关闭管道:所有写操作完成后再关闭写端,确保读端能正确触发EOF。
  3. 改用while循环读取数据,直到read返回0(表示已到EOF)。
  4. 增加pipe()创建失败的错误处理,提升程序健壮性。

修正后输出

Pipe is Open
0
1
2
3
4

内容的提问来源于stack exchange,提问作者Cláudio Santos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:37:01