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

从管道读取后read函数阻塞进程问题求助

管道read阻塞进程的问题分析与解决

问题原因

你的代码里,主进程创建管道后没有关闭管道的两个文件描述符fd[0]和fd[1]。根据管道的工作规则:只有当所有指向管道写端的文件描述符都被关闭时,读端的read调用才会返回0(表示EOF),否则read会一直阻塞等待数据。

在你的执行流程里:

  1. 主进程创建管道后fork出子进程1,主进程自身仍持有管道的读写两端
  2. 子进程12关闭了写端fd[1]并退出,但主进程的fd[1]还处于打开状态
  3. 子进程1的read循环会一直阻塞,因为它认为还有进程可能往管道里写入数据

解决方案

在主进程的default分支里,fork完成后立即关闭管道的两个文件描述符——主进程不需要使用这个管道,保留打开的描述符会干扰管道的EOF判断。

修改后的代码:

#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<string.h>
#include <unistd.h>

int nbrecar=5;

int main()
{
    int fd[2];
    pipe(fd);
    char *buffer=(char *)malloc(sizeof(char)*256);
    int pid=fork();
    
    switch(pid)
    {
        case 0://fils 1 //pere 2
            int pid2=fork();
            if (pid2==0)//fils 12 // pere 3
            {
                close(fd[0]);
                while(nbrecar>1)
                {
                    if(sprintf(buffer,"le nbre des cars restant:%i\n",nbrecar-1)==-1){printf("Erreur");};
                    nbrecar--;
                    write(fd[1],buffer,strlen(buffer));
                }
                close(fd[1]);
                exit(0);
            }
            else//fils 1
            {
                close(fd[1]);
                char c;
                while(read(fd[0],&c,1)==1)
                {printf("%c",c);};
                close(fd[0]);       
                exit(8);            
            }
            break;
        default:
            // 主进程关闭管道的读写端
            close(fd[0]);
            close(fd[1]);
            wait(NULL);
            free(buffer);
    }
    return 0;
}

验证说明

修改后,主进程关闭了管道的两端,当子进程12关闭写端并退出后,管道的所有写端都已关闭,子进程1的read会返回0,循环正常退出,进程不再阻塞,能够正常结束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 14:55:15