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

C语言使用fork+pipe实现ls|sort时pipefd[0]无输出无法打印问题

问题代码错误点
  • 子进程错误调用wait(NULL):wait系统调用的作用是等待当前进程的自身子进程退出,而执行sort的子进程本身没有创建任何子进程,该调用会直接报错返回,逻辑完全错误,也无法实现等待父进程写入数据的效果。
  • 管道多余文件描述符未完全关闭:每个进程都持有管道读写端的独立副本,执行ls的父进程仅需要管道写端,必须主动关闭不需要的读端;执行sort的子进程仅需要管道读端,必须主动关闭不需要的写端。如果管道的写端没有在所有进程中关闭,读端进程会一直阻塞等待数据,不会收到EOF,sort就不会输出结果。
  • 资源清理代码位置错误:execl调用成功后会完全替换当前进程的地址空间,后续的close代码永远不会执行,必须把管道描述符的关闭操作放在execl之前。
修正后完整代码
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
int main(){
    int pipefd[2];
    if (pipe(pipefd) == -1) {
        perror("pipe error");
        return 1;
    }
    int child = fork();
    if (child == -1) {
        perror("fork error");
        return 1;
    }
    if(!child){
        // 子进程执行sort,读取管道内容
        dup2(pipefd[0], 0);
        // 关闭子进程不需要的管道写端、已重定向的读端
        close(pipefd[1]);
        close(pipefd[0]);
        execl("/bin/sort", "sort", NULL);
        perror("execl sort error");
        return 1;
    }else{
        // 父进程执行ls,写入管道
        dup2(pipefd[1], 1);
        // 关闭父进程不需要的管道读端、已重定向的写端
        close(pipefd[0]);
        close(pipefd[1]);
        execl("/bin/ls", "ls", NULL);
        perror("execl ls error");
        return 1;
    }
    return 0;
}
补充说明

父进程执行ls退出后,系统会自动关闭所有残留的文件描述符,此时管道写端完全关闭,sort读取到EOF后就会对所有输入排序并输出到标准输出。如果需要等待子进程执行完毕,可以在父进程逻辑中添加waitpid相关处理,不会影响管道数据的正常传递。

内容的提问来源于stack exchange,提问作者Juzar Antri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:57:01