免费注册 查看新帖 |

Chinaunix

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

[已解决]关于FIFO的O_NONBLOCK标志的一个问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-04 19:34 |只看该作者 |倒序浏览
apue介绍FIFO 时,提到关于open FIFO  时O_NONBLOCK标志位对read()系统调用的影响

When we open a FIFO, the nonblocking flag (O_NONBLOCK) affects what happens.

In the normal case (O_NONBLOCK not specified), an open for read-only blocks until some other process opens the FIFO for writing. Similarly, an open for write-only blocks until some other process opens the FIFO for reading.

If O_NONBLOCK is specified, an open for read-only returns immediately. But an open for write-only returns 1 with errno set to ENXIO if no process has the FIFO open for reading.

我写了一个测试程序,想测试一下 红色标识 部分的内容
可是我发现这种阻塞情况并没有发生

测试程序如下
  1. #include <stdio.h>
  2. #include <sys/stat.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <sys/fcntl.h>

  6. int main(void)
  7. {
  8.         int fd;
  9.         int n;
  10.         int flag;
  11.         char line[1024];

  12.         if (mkfifo("./test.txt", 0666) == -1)
  13.         {
  14.                 printf("mkfifo() error\n:%s\n", strerror(errno));
  15.                 exit(0);
  16.         }

  17.         printf("open for read-only and with O_NONBLOCK set\n");
  18.         if ((fd = open("./test.txt", O_RDONLY | O_NONBLOCK)) == -1)
  19.         {
  20.                 printf("open error\n");
  21.                 exit(0);
  22.         }

  23.         if ((n = read(fd, line, 1024)) == 0)
  24.         {
  25.                 printf("read() returned immediately\n");
  26.         }
  27.         else if (n < 0)
  28.         {
  29.                 printf("read() error\n");
  30.         }
  31.         else
  32.         {
  33.                 line[n] = 0;
  34.                 printf("read something:%s\n", line);
  35.         }

  36.         if ((flag = fcntl(fd, F_GETFL, 0)) == -1)
  37.         {
  38.                 printf("fcntl() error for F_GETFL\n");
  39.                 exit(0);
  40.         }

  41.         printf("open for read-only, with O_NONBLOCK clear\n");
  42.         flag &= ~O_NONBLOCK;
  43.         if (fcntl(fd, F_SETFL, flag) == -1)
  44.         {
  45.                 printf("fcntl() error for F_SETFL\n");
  46.                 exit(0);
  47.         }

  48.         if ((n = read(fd, line, 1024)) == 0)
  49.         {
  50.                 printf("read() returned immediately\n");
  51.         }
  52.         else if (n < 0)
  53.         {
  54.                 printf("read() error\n");
  55.         }
  56.         else
  57.         {
  58.                 line[n] = 0;
  59.                 printf("read something:%s\n", line);
  60.         }

  61.         return 0;
  62. }
复制代码


运行结果如下:
open for read-only and with O_NONBLOCK set
read() returned immediately
open for read-only, with O_NONBLOCK clear
read() returned immediatel

[ 本帖最后由 zhuhefang2006 于 2009-2-6 17:30 编辑 ]

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2009-02-06 00:06 |只看该作者
如果你把测试O_NONBLOCK部分的代码去掉,
直接测试BLOCK部分,read是阻塞的,
具体原因你分析吧,我也不知道。

论坛徽章:
0
3 [报告]
发表于 2009-02-06 04:03 |只看该作者
前几天记得有人问过,我当时给了个例子代码链接的。

你用父子进程来操作FIFO文件,一个进程读,一个进程写来试一下。

论坛徽章:
0
4 [报告]
发表于 2009-02-06 17:15 |只看该作者
原帖由 lenovo 于 2009-2-6 00:06 发表
如果你把测试O_NONBLOCK部分的代码去掉,
直接测试BLOCK部分,read是阻塞的,
具体原因你分析吧,我也不知道。


按照你的方法直接以O_RDONLY方式打开,发现read果然阻塞了
可是不知道原因呢
fcntl对O_NONBLOCK设置是有效的
难道O_NONBLOCK没有对文件读操作起作用?

论坛徽章:
0
5 [报告]
发表于 2009-02-06 17:30 |只看该作者
不好意思,原来是我搞错了,作者是说O_NONBLOCK会阻塞open(),而我的测试代码却是测试的read()操作

新的测试代码如下:

  1. /*
  2. When we open a FIFO, the nonblocking flag (O_NONBLOCK) affects what happens.

  3. In the normal case (O_NONBLOCK not specified),
  4. an open for read-only blocks until some other process opens the FIFO for writing.
  5. Similarly, an open for write-only blocks until some other process opens the FIFO for reading.

  6. If O_NONBLOCK is specified, an open for read-only returns immediately.
  7. But an open for write-only returns -1 with errno set to ENXIO if no process has the FIFO open for reading.

  8. */

  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <errno.h>
  13. #include <sys/fcntl.h>

  14. int main(void)
  15. {
  16.         int fd;
  17.        
  18.         if (mkfifo("./test.txt", 0666) == -1)
  19.         {
  20.                 printf("mkfifo() error\n:%s\n", strerror(errno));
  21.                 exit(0);
  22.         }

  23.         system("ls -l ./test.txt");

  24.         printf("open for read-only and with O_NONBLOCK set\n");
  25.         if ((fd = open("./test.txt", O_RDONLY | O_NONBLOCK)) == -1)
  26.         {
  27.                 printf("open error\n");
  28.                 exit(0);
  29.         }

  30.         printf("open() returned immediately with O_NONBLOCK set\n");
  31. //--------------
  32.         if ((fd = open("./test.txt", O_RDONLY)) == -1)
  33.         {
  34.                 printf("open error\n");
  35.                 exit(0);
  36.         }

  37.         printf("This sentence will not appear, because open() without O_NONBLOCK will block\n");

  38.         return 0;
  39. }
  40.        

  41.        
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP