免费注册 查看新帖 |

Chinaunix

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

[求助]多个pipe怎么写 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-05 23:09 |只看该作者 |倒序浏览
本帖最后由 buzzerrookie 于 2012-03-05 23:36 编辑

我想用C语言实现一下 ls -l | more | wc,写的代码如下,但没有输出,不知道哪里错了,请各位帮帮忙,谢谢各位。

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/wait.h>

  4. int main()
  5. {
  6.         pid_t pid[3];
  7.         int pipe_fd[2];
  8.         int pipe_fd2[2];
  9.         int status;

  10.         char *prog1[3] = {"/bin/ls", "-l", NULL};
  11.         char *prog2[2] = {"/bin/more", NULL};
  12.         char *prog3[2] = {"/usr/bin/wc", NULL};

  13.         if(pipe(pipe_fd) < 0){
  14.                 perror("pipe 1 failed");
  15.         }
  16.         if(pipe(pipe_fd2) < 0){
  17.                         perror("pipe 2 failed");
  18.                 }
  19.         if((pid[0] = fork()) < 0){
  20.                 perror("fork failed");
  21.         }
  22.         if(pid[0] == 0){
  23.                 close(pipe_fd[0]);
  24.                 dup2(pipe_fd[1], 1);
  25.                 close(pipe_fd[1]);
  26.                 execvp(prog1[0], prog1);

  27.         }
  28.         if(pid[0] > 0){
  29.                 pid[1] = fork();
  30.                 if(pid[1] == 0){
  31.                         close(pipe_fd[1]);
  32.                         dup2(pipe_fd[0], 0);
  33.                         close(pipe_fd[0]);

  34.                         close(pipe_fd2[0]);
  35.                         dup2(pipe_fd2[1], 1);
  36.                         close(pipe_fd2[1]);
  37.                         execvp(prog2[0], prog2);
  38.                 }
  39.                 if(pid[1]>0){
  40.                         pid[2] = fork();
  41.                         if(pid[2] == 0){
  42.                                 close(pipe_fd2[1]);
  43.                                 dup2(pipe_fd2[0], 0);
  44.                                 close(pipe_fd2[0]);

  45.                                 execvp(prog3[0], prog3);
  46.                         }
  47.                 }
  48.                 close(pipe_fd[0]);
  49.                 close(pipe_fd[1]);
  50.                 close(pipe_fd2[0]);
  51.                 close(pipe_fd2[1]);
  52.                 waitpid(pid[1], &status, 0);
  53.         }
  54.         return 0;
  55. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2012-03-06 11:22 |只看该作者
推测:是不是造成了死锁了
也是半生水平呵呵
把管道1 的关闭工作放在创建运行wc的那个子进程之前就行了,我试了一下应该是成功的

论坛徽章:
0
3 [报告]
发表于 2012-03-06 11:49 |只看该作者
本帖最后由 luckysir 于 2012-03-07 15:39 编辑

进一步推测:因为第二个进程运行more,第三个运行wc,而这俩程序都是要看到文件尾才会收工的吧,但是他俩的标准输入现在都成了管道,该管道打开的时候没有指定O_NONBLOCK,所以当管道中没有数据的时候read要么阻塞住,要么在所有的写端fd都被关闭之后返回0,因此别忘了父进程打开的管道没关闭,因此more阻塞住了,随之又阻塞了wc,可是parent还在wait  more。

论坛徽章:
0
4 [报告]
发表于 2012-03-06 12:20 |只看该作者
上边描述思路可能是对的,可是细节有错误,刚睡醒的时候脑子就是有些兴奋却不清醒,见谅

应该是parent不及时关闭管道一,结果导致fork后被wc那个进程继承了,然后more和wc互相阻塞。

可能这个推测还是有偏差。)

论坛徽章:
0
5 [报告]
发表于 2012-03-06 12:36 |只看该作者
回复 4# luckysir


    非常感谢,我先按您说的这么写吧,尽管我还是不太明白其中的原理。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP