免费注册 查看新帖 |

Chinaunix

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

[C] open打开管道,加上O_NONBLOCK就失败? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-30 22:51 |只看该作者 |倒序浏览
10可用积分
写了一个小程序,先mkfifo打开一个管道,再open它。如果加上O_NONBLOCK就失败,源代码:
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<string.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
int main(void){
char fn[]="myfifo";
int  ret=mkfifo(fn,S_IRUSR|S_IWUSR);
if(ret==-1){
  printf("mkfifo error:%s\n",strerror(errno));
  return 1;
}
int fd=open(fn,O_WRONLY|O_NONBLOCK,S_IRWXU);
if(fd==-1){
  printf("open error:%s\n",strerror(errno));
  return 1;
}
close(fd);
unlink(fn);
return 0;
}

执行的结果是
[kg@localhost gcc fn.c && ./a.out
open error:No such device or address

如果我去掉open函数当中的O_NONBLOCK就能正确执行。或者,我打开的对象是普通的文件,也能正确执行,
int main(void){
char fn[]="myf";
int fd=open(fn,O_CREAT|O_WRONLY|O_NONBLOCK,S_IRWXU);
if(fd==-1){
  printf("open error:%s\n",strerror(errno));
  return 1;
}
int w=write(fd,"hello!",4);
if(w==-1){
  printf("write error:%s\n",strerror(errno));
  return 1;
}
printf("w=%d\n",w);
close(fd);
//unlink(fn);
return 0;
}

为什么管道上面就不能O_NONBLOCK呢?

谢谢!!!

最佳答案

查看完整内容

你想要的是不是这个?

论坛徽章:
0
2 [报告]
发表于 2009-04-30 22:51 |只看该作者
你想要的是不是这个?


  1. #include<sys/types.h>
  2. #include<sys/stat.h>
  3. #include<errno.h>
  4. #include<string.h>
  5. #include<stdio.h>
  6. #include<unistd.h>
  7. #include<fcntl.h>
  8. int
  9. main (void)
  10. {
  11.   char buf[1024];
  12.   char fn[] = "myfifo";
  13.   int ret = mkfifo (fn, S_IRUSR | S_IWUSR);
  14.   if (ret == -1)
  15.     {
  16.       printf ("mkfifo error:%s\n", strerror (errno));
  17.       return 1;
  18.     }
  19.   int rd = open (fn, O_RDONLY | O_NONBLOCK);
  20.   int fd = open (fn, O_WRONLY | O_NONBLOCK, S_IRWXU);
  21.   if (fd == -1)
  22.     {
  23.       printf ("open error:%s\n", strerror (errno));
  24.       return 1;
  25.     }
  26.   write (fd, "hello", 5);
  27.   read (rd, buf, 5);
  28.   write (1, buf, 5);
  29.   close (fd);
  30.   unlink (fn);
  31.   return 0;
  32. }
复制代码

论坛徽章:
0
3 [报告]
发表于 2009-04-30 23:18 |只看该作者
man fifo

A  process can open a FIFO in non-blocking mode.  In this case, opening
       for read only will succeed even if no-one has opened on the write  side
       yet;  opening  for  write  only will fail with ENXIO (no such device or
       address) unless the other end has already been opened.

论坛徽章:
0
4 [报告]
发表于 2009-05-01 13:52 |只看该作者
原帖由 win_hate 于 2009-4-30 23:18 发表
man fifo



谢谢,从man的内容看起来,非阻塞的管道不能单独用作写。但是在shell下面做的实验并不是这样的结果,不知道其中有什么区别。实现如下:

$mkfifo f1
$echo "kk">f1

然后echo命令会阻塞在那里,直到另一个终端窗口去read t <f1为止。

但是如果我
$exec 3<>f1
我就可以以非阻塞的方式对f1进行写入

$echo "line 1">&3
$echo "line 2">&3
这里都没有阻塞,在另一个终端窗口里面cat f1的话会把刚才的line1和line2都输出出来。

问题就是: 既然shell也是用C实现的调用系统api,那么为什么C编程的时候不能对一个管道进行非阻塞的写入呢,就像上面的shell做到的一样。

还望dx继续指教啊!!!!!

论坛徽章:
0
5 [报告]
发表于 2009-05-01 14:47 |只看该作者
man 里的 unless the other end has already been opened.

就是说必须先有一个进程把该 fifo 以读方式打开。你的 exec 3<>f1 不是已按读方式打开了么?

[ 本帖最后由 win_hate 于 2009-5-1 14:50 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2009-05-01 18:36 |只看该作者
原帖由 win_hate 于 2009-5-1 14:54 发表
你想要的是不是这个?


#include
#include
#include
#include
#include
#include
#include
int
main (void)
{
  char buf[1024];
  char fn[] = "myfifo";
  int ret = mkfifo (fn, S_IRUSR |  ...

谢谢,dx说的就是我想要的,敬分!!!!!!!!!!!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP