免费注册 查看新帖 |

Chinaunix

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

非阻塞FIFO读的时候产生的错误,请教为什么? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-06-22 17:11 |只看该作者 |倒序浏览
非阻塞读FIFO的程序: read_fifo.c


  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <errno.h>

  6. #define FIFO_PATH   "/tmp/test_fifo"
  7. #define LEN  1000

  8. int main(void)
  9. {
  10.      int fd, n;
  11.      char buf[LEN] ;

  12.      if (mkfifo(FIFO_PATH, 0600) < 0) {        // 创建FIFO
  13.           if (errno != EEXIST) {
  14.                perror("mkfifo");
  15.                exit(-1);
  16.           }
  17.      }

  18.      if ((fd = open(FIFO_PATH, O_RDONLY|O_NONBLOCK)) < 0) {     // 非阻塞读打开FIFO
  19.           perror("open fifo");
  20.           exit(-1);
  21.      }

  22.      while(1) {                     // 循环读FIFO
  23.           n = read(fd, buf, LEN);
  24.           printf("n = %d\n", n);

  25.           if (n < 0) {              // 读错误,退出
  26.                perror("read");
  27.                exit(-1);
  28.           }

  29.           if (n == 0) {             // 未读到数据, 休眠2秒, 继续读
  30.                sleep(2);
  31.                continue;
  32.           }
  33.      }

  34.      close(fd);

  35.      return 0;
  36. }
复制代码



阻塞写FIFO的程序: write_fifo.c


  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <errno.h>

  6. #define FIFO_PATH   "/tmp/test_fifo"
  7. #define LEN 6800

  8. int main(void)
  9. {
  10.      int fd, n;
  11.      int sum = 0;
  12.      char buf[LEN] ;

  13.      if ((fd = open(FIFO_PATH, O_WRONLY)) < 0) {         // 阻塞只写方式打开FIFO
  14.           perror("open fifo");
  15.           exit(-1);
  16.      }

  17. // 循环写,直到把全部数据写完
  18.      while(1) {
  19.           n = write(fd, &buf[sum], LEN-sum);         // 写FIFO
  20.           printf("n = %d\n", n);

  21.           if (n < 0) {                         // 写错误退出
  22.                perror("read");
  23.                exit(-1);
  24.           }

  25.           sum += n;                 //  累加已经写的字节数

  26.           if (sum == LEN)           // 如果已经写完,退出
  27.                break;
  28.      }

  29.      printf("sum = %d\n", sum);

  30.      close(fd);

  31.      return 0;
  32. }
复制代码


运行结果:
read_fifo的输出:
n = 0
n = 1000
n = 1000
n = 1000
n = 1000
n = 96
n = -1
read: Resource temporarily unavailable

write_fifo的输出:
n = 4096
断开的管道

请教什么原因产生的这种错误?

PS: 也不是总是产生错误, 有时也会正确运行

[ 本帖最后由 grt8000 于 2006-6-22 17:13 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-06-22 17:17 |只看该作者
应该是linux系统下的吧
有一个系统默认的PIPE_BUF = 4096

一种可以避免的法子是在read 和 write之前,用select进行判断是否可读写.

[ 本帖最后由 yeehya 于 2006-6-22 17:22 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2006-06-22 17:27 |只看该作者
是在Linux平台.
FIFO好象有点不一样, 为什么会报错呢? 看起来象是读先错了, 是什么原因?
而且程序有时会运行正常,有时会出这种错误.

论坛徽章:
0
4 [报告]
发表于 2006-06-22 17:29 |只看该作者
如果把非阻塞读换成阻塞读,即是去掉read_fifo.c中的O_NONBLOCK, 程序运行就没出过错.

论坛徽章:
0
5 [报告]
发表于 2006-06-23 09:03 |只看该作者
O_NONBLOCK enabled, n <= PIPE_BUF
If there is room to write n bytes to the pipe, then write(2) succeeds immediately, writing all n bytes; otherwise write(2) fails, with errno set to EAGAIN

论坛徽章:
0
6 [报告]
发表于 2006-06-23 09:58 |只看该作者
原帖由 yeehya 于 2006-6-23 09:03 发表
O_NONBLOCK enabled, n <= PIPE_BUF
If there is room to write n bytes to the pipe, then write(2) succeeds immediately, writing all n bytes; otherwise write(2) fails, with errno set to EAGAIN

写FIFO的时候是阻塞写的,只是在读的时候为非阻塞读

论坛徽章:
0
7 [报告]
发表于 2006-07-03 23:09 |只看该作者
fifo的读写和socket的读写基本是一样的,你的程序的可靠性也就是前几次了。

论坛徽章:
0
8 [报告]
发表于 2006-07-04 08:25 |只看该作者
对非阻塞的管道就是有这个问题,编程解决。

论坛徽章:
0
9 [报告]
发表于 2006-07-04 20:30 |只看该作者
读得比写得快,当然读不到
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP