我一直在使用进程间通信用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之后,我找不到任何(简单)解释为什么我要重置文件描述符的标志,如果我想读取非阻塞和写阻塞。
任何人都有解释或我做错了吗?
答案 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 允许在这种情况下返回错误,并且不需要 这些常量具有相同的值,因此是一个可移植的应用程序 应该检查两种可能性。