免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2992 | 回复: 2
打印 上一主题 下一主题

我用管道重定向IO,为什么有时候会出现Broken pipe,有时候正常? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-31 19:15 |只看该作者 |倒序浏览
5可用积分
我之前提过一个问题(http://bbs.chinaunix.net/thread-1776837-1-1.html),这个不涉及文件IO的类似程序,总能正常运行。
但是现在我加入了文件IO,有时候能正常运行,有时候出现Broker pipe. 不知道是为什么
还请各位高人继续指教啊。

-------------------------------------------------------------------------------
建立一个命令行程序,做加法
> cat calc.C
#include<iostream.h>
int main(void){
  int a , b;
  while(cin>>a>>b){
    cout<<a+b<<'\n';
  }
  return 0;
}
编译得到calc.
>cat in.txt   
20 30
5 6
然后用一个管道程序my,它读取in.txt,通过管道发送给calc作为stdin,读取calc的stdout,并写入到文件out.txt。后面是源代码。
------------------------------------------------------------------------------
很奇怪,执行a.out的时候,有时候能成功,也就是out.txt的内容是
50
11
有时候执行a.out就只有一个数字
50
有时候执行a.out,出现Broker pipe错误。
这是为什么?

>cat my.C
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(void){
  int p2my[2];
  int my2p[2];
  char bufin[128]={0};
  char bufout[128]={0};
  if(pipe(p2my) || pipe(my2p)){
    printf("pipe failed\n");
    exit(1);
  }
  int pid=fork();
  if(pid<0){
    printf("fork failed\n");
    exit(1);
  }
  if(pid>0){//father
    close(p2my[0]);
    close(my2p[1]);
    int fdin=open("in.txt",O_RDONLY);
    int fdout=open("out.txt",O_RDWR|O_CREAT,O_NONBLOCK);
    int i,r=0;
    do{
      for(i=0;i<128;++i){bufin[ i ]=0;bufout[ i ]=0;}
      r=read(fdin,bufin,sizeof(bufin));
      write(p2my[1],bufin,sizeof(bufin));
      read( my2p[0],bufout,sizeof(bufout));
      write(fdout,  bufout,sizeof(bufout));
    }while(r!=0);
    close(fdin);
    close(fdout);
  }else if(pid==0){//child
    close(p2my[1]);
    close(my2p[0]);
    close(0);
    close(1);
    dup2(p2my[0],0);
    dup2(my2p[1],1);
    execl("my",NULL);
  }
  return 0;
}

最佳答案

查看完整内容

回复 1# kgisme170 子进程execl程序,应该是还没启动起来,就往管道中输出内容了吧?你可以试一下这个解决办法:fork后,在主程序中休眠1s。

论坛徽章:
4
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11IT运维版块每日发帖之星
日期:2016-08-11 06:20:00IT运维版块每日发帖之星
日期:2016-08-15 06:20:00
2 [报告]
发表于 2010-08-31 19:15 |只看该作者
回复 1# kgisme170

子进程execl程序,应该是还没启动起来,就往管道中输出内容了吧?
你可以试一下这个解决办法:fork后,在主程序中休眠1s。

论坛徽章:
0
3 [报告]
发表于 2010-09-01 09:57 |只看该作者
自己知道了:
因为从文件读入的时候,一次读入就结束了(虽然是两行,但是还是一次read就结束,同理写入管道的时候也是一次结束。所以主程序的while循环里面,应该只包含从管道读出结果的过程,修改如下:

> cat -n wrap.C
     1  #include<stdio.h>
     2  #include<stdlib.h>
     3  #include<unistd.h>
     4  #include<sys/types.h>
     5  #include<sys/stat.h>
     6  #include<fcntl.h>
     7  int main(void){
     8    int p2my[2];
     9    int my2p[2];
    10    char bufin[128]={0};
    11    char bufout[128]={0};
    12    if(pipe(p2my) || pipe(my2p)){
    13      printf("pipe failed\n");
    14      exit(1);
    15    }
    16    int pid=fork();
    17    if(pid<0){
    18      printf("fork failed\n");
    19      exit(1);
    20    }
    21    if(pid>0){//father
    22      close(p2my[0]);
    23      close(my2p[1]);
    24      int fdin=open("in.txt",O_RDONLY);
    25      int fdout=open("out.txt",O_RDWR|O_CREAT,O_NONBLOCK);
    26      int r=read(fdin,bufin,sizeof(bufin));
    27      write(p2my[1],bufin,sizeof(bufin));
    28      do{
    29        for(int i=0;i<128;++i){bufout[i]=0;}
    30        r=read( my2p[0],bufout,sizeof(bufout));
    31        write(/*STDOUT_FILENO*/fdout,  bufout,sizeof(bufout));
    32      }while(r!=0);
    33      close(fdin);
    34      close(fdout);
    35    }else if(pid==0){//child
    36      close(p2my[1]);
    37      close(my2p[0]);
    38      close(0);
    39      close(1);
    40      dup2(p2my[0],0);
    41      dup2(my2p[1],1);
    42      execl("my",NULL);
    43    }
    44    return 0;
    45  }

现在运行就没有问题了!!!!!
还是感谢回答了问题的人!!!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP