2013-01-22 53 views
0

我使用mkfifo创建了一个命名管道,并在其上打开了一个读写器。 然后,我开始在同一个fifo上打开另一个读写器,但打开返回ENXIO。FIFO上的多个读写器(命名管道)

std::string n = "/tmp/test"; 
int err; 
err = mkfifo(n.c_str(), 0666); 
if (err == -1) 
    return NULL; 

int pipefd[2]; 
pipefd[0] = open(n.c_str(), O_RDONLY | O_NONBLOCK); 
pipefd[1] = open(n.c_str(), O_WRONLY | O_NONBLOCK); 
open(n.c_str(), O_RDONLY | O_NONBLOCK); // fails - ENXIO 
open(n.c_str(), O_WDONLY | O_NONBLOCK); // fails - ENXIO 

当打开管道以允许多次打开时,是否有任何特定的标记需要设置?我已经阅读了文档,但没有找到解释,为什么上面会失败(我只在Cygwin上测试过)。由于described here,在fifo上打开多个读写器是完全有效的。

我将使用它来复制WinAPI的OpenEvent功能,该功能需要由单独的项目使用。

编辑:测试了这在Debian和Ubuntu上 - 两者都符合POSIX并允许多个编写器(因此上面的代码不会出现任何问题)。 Cygwin的实现被破坏(即不符合POSIX)。

+2

除非你做的事情非常奇怪,否则通常要打开两个管道,每个方向一个。读取*和*从同一个进程中写入相同的管道是没有意义的。使用两个管道,进程1首先读取并写入第二个,而进程2读取第二个并写入第一个。 – Amadan

+0

@Amadan我正在使用管道模拟Set/ResetEvent WaitForSingle/MultipleObjects,所以它只需要一个管道。 –

回答

1

管道只有一个读取器进程和写入器进程可能。在POSIX管道中是单向的。

改为使用套接字文件。它是全双工的并且允许多个进程通信。

+0

我不认为这是可行的。没有命名套接字这样的东西。 –

+0

我的意思是本地域名套接字,通常称为“UNIX域套接字” – clover

+0

unix.7手册页 – clover

0

尝试删除O_NONBLOCK

而且第四次调用open函数时,它必须使用O_WRONLY。

相关问题