Linux fifo(命名管道)O_NONBLOCK打破了管道

时间:2013-02-17 16:54:40

标签: linux posix pipe fifo

我一直在使用进程间通信用C ++编写一个用于Linux的小程序。当尝试使用一个进程以非阻塞方式读取并使用另一个进程写入(阻塞)时,我遇到了问题。问题看起来像这样,当父级尝试使用O_NONBLOCK(或O_NDELAY)读取管道时,它从不读取单个字节,当子级尝试在管道上写入时,它会失败并且{ {1}}发送断管信号。以下是代码示例:

SIGPIPE

我终于找到了一种方法,可以在非阻塞打开电话后立即使用// Parent process mkfifo(PROC_COPROC, 0666); int fd_co = open(PROC_COPROC, O_RDONLY | O_NDELAY); char c; int n; fcntl(fd_co,F_SETFL,0); //fix it while ((n = read(fd_co, &c, 1)) > 0) { printf("%c", c); } close(fd_co); // Child process int fd = open(PROC_COPROC, O_WRONLY | O_APPEND); if ( fd != -1 ) { write( fd , "message\n" , 8); //Fails here if flag not set } else printf("Ne peut pas ecrire sur le fifo\n"); close(fd); 解决此问题。

在阅读man page之后,我找不到任何(简单)解释为什么我要重置文件描述符的标志,如果我想读取非阻塞和写阻塞。

任何人都有解释或我做错了吗?

1 个答案:

答案 0 :(得分:3)

O_NDELAY的“问题”是,当没有可用数据时,读取返回-1并将errno设置为EAGAIN。因此,您必须为read和errno测试-1的返回值,然后再次阅读。

你的“修复”只重置O_NDELAY,如果没有任何内容可以从FIFO中读取,它会再次进行读取。

另见read

  

返回值
  ...出错时,返回-1,并正确设置errno。

     

<强>错误
    EAGAIN 文件描述符fd指的是套接字以外的文件                 被标记为非阻塞(O_NONBLOCK),并且读取将被阻止    EAGAIN EWOULDBLOCK
                文件描述符fd指的是套接字并已被标记                 非阻塞(O_NONBLOCK),读取将阻塞。 POSIX.1-2001                 允许在这种情况下返回错误,并且不需要                 这些常量具有相同的值,因此是一个可移植的应用程序                 应该检查两种可能性。

如果在您的情况下阻止是个问题,您也可以考虑使用selectpoll作为@BasileStarynkevitch建议。