LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 885|回复: 6

这个pipe read 端为啥不返回0

[复制链接]
发表于 2006-11-9 12:16:34 | 显示全部楼层 |阅读模式
process 1: 先行
pipe(pipeFd);
close(pipeFd[1]);
read(pipeFd[0], pipeBuf, PIPE_BUF_SIZE); //blocking


process 2:
close(pipeFd[0]);
close(pipeFd[1]);

我是想通过close pipe的write端来结束process1的,可是结果process1一直在read处blocking,不返回;按理说pipe的write端关闭,read端应该返回0才对啊?
发表于 2006-11-9 13:48:30 | 显示全部楼层
试试在process 1中的close(pipeFd[1])之后加入一个延时sleep(),以保证process2关闭了pipeFd[1]写端了process1再去读。延时的时间自己试一下要多少。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-11-9 14:09:10 | 显示全部楼层
Post by xlwcat
试试在process 1中的close(pipeFd[1])之后加入一个延时sleep(),以保证process2关闭了pipeFd[1]写端了process1再去读。延时的时间自己试一下要多少。

我就要让process1先处于blocking状态,然后process2告诉process1 pipe输入结束,让process1可以终止;所以你说的这种方法对我不适用。
回复 支持 反对

使用道具 举报

发表于 2006-11-9 14:20:15 | 显示全部楼层
  1. #include <unistd.h>
  2. #include <sys/types.h>
  3. #include <errno.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>

  7. int main(int argc, char **argv)
  8. {
  9.         int pipe_fd[2];
  10.         pid_t pid;
  11.         char r_buf[100];
  12.         char w_buf[4];
  13.         char *p_wbuf;
  14.         int r_num;
  15.         int cmd;
  16.         memset(r_buf, 0, sizeof(r_buf));
  17.         memset(w_buf, 0, sizeof(w_buf));
  18.         p_wbuf=w_buf;
  19.         if(pipe(pipe_fd) < 0)
  20.         {
  21.                 printf("pipe create error!\n");
  22.                 return -1;
  23.         }

  24.         if((pid=fork()) == 0)
  25.         {
  26. //              printf("\n");
  27.                 close(pipe_fd[1]);
  28.                 while(1)
  29.                 {
  30.                         sleep(3);
  31.                         r_num=read(pipe_fd[0], r_buf, 100);
  32.                         if(r_num != 0)
  33.                         {
  34.                                 printf("read num is %d", r_num);
  35.                                 printf(" the data read from the pipe is %d\n", atoi(r_buf));
  36.                         }
  37.                         else
  38.                         {
  39.                                 break;
  40.                         }
  41.                 }
  42.                 close(pipe_fd[0]);
  43.                 exit(1);
  44.         }
  45.         else if(pid >0){
  46.                 close(pipe_fd[0]);
  47.                 strcpy(w_buf, "111");
  48.                 if(write(pipe_fd[1], w_buf, 4) != -1)
  49.                 {
  50.                         printf("parent write over\n");
  51.                 }
  52.                 close(pipe_fd[1]);
  53.                 printf("parent close fd[1] over\n");
  54.                 sleep(10);
  55.         }
  56. }
复制代码


俺写了一个测试的代码,父process先写一个串进去,然后关闭写端,子process先blocking 3秒,等待父process处理完并关闭写端,然后从读端去读,不管怎么样都不会在read的最低点blocking啊。。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-11-9 14:54:05 | 显示全部楼层
你先让子进程sleep了3秒,足够父进程跑完了,此时父进程已经close pipe了,子进程再去读pipe的时候自然就能见到end of file了,都没有block过
回复 支持 反对

使用道具 举报

发表于 2006-11-9 15:15:30 | 显示全部楼层
  1. #include <unistd.h>
  2. #include <sys/types.h>
  3. #include <errno.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>

  7. int main(int argc, char **argv)
  8. {
  9.         int pipe_fd[2];
  10.         pid_t pid;
  11.         char r_buf[100];
  12.         char w_buf[4];
  13.         char *p_wbuf;
  14.         int r_num;
  15.         int cmd;
  16.         memset(r_buf, 0, sizeof(r_buf));
  17.         memset(w_buf, 0, sizeof(w_buf));
  18.         p_wbuf=w_buf;
  19.         if(pipe(pipe_fd) < 0)
  20.         {
  21.                 printf("pipe create error!\n");
  22.                 return -1;
  23.         }

  24.         if((pid=fork()) == 0)
  25.         {
  26. //              printf("\n");
  27.                 close(pipe_fd[1]);
  28.                 while(1)
  29.                 {
  30.                         sleep(3);
  31.                         r_num=read(pipe_fd[0], r_buf, 100);                        
  32.                         printf("read num is %d", r_num);
  33.                         printf(" the data read from the pipe is %d\n", atoi(r_buf));                        
  34.                 }
  35.                 close(pipe_fd[0]);
  36.                 exit(1);
  37.         }
  38.         else if(pid >0)
  39.         {
  40.                 close(pipe_fd[0]);
  41.                 strcpy(w_buf, "111");
  42.                 if(write(pipe_fd[1], w_buf, 4) != -1)
  43.                 {
  44.                         printf("parent write over\n");
  45.                 }
  46.                 sleep(10);
  47.                 close(pipe_fd[1]);
  48.                 printf("parent close fd[1] over\n");
  49.         }
  50. }
复制代码


改一下代码,让父进程sleep(10)秒再去关闭pipe的写端,子进程还是照样先sleep(3)秒。执行结果是这样子的,父进程写完"111"串后就休眠10秒,子进程休眠3秒后苏醒读pipe,读到111,由于是一个永远为真的循环,再次休眠3秒后再次读pipe,这时候因为父进程不再写入数据,并且写端未被关闭,所以blocking,父进程休眠10秒时间到了以后苏醒关闭pipe的写端,那么子进程blocking的那次read就会返回,返回值是0。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-11-9 16:20:55 | 显示全部楼层
sorry,最后发现是我自己程序的问题,因为多了一个dup 的fd指向pipe[1],所以相对而言close少了一次,所以没能真正释放pipe。
最后,谢谢讨论
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表