2012-07-05 205 views
0

我为IPC使用FIFO。但是他们执行一些奇怪的行为。 至于代理,我在这里发布一些代码,可以编译和运行。 附加信息,我在Linux Ubuntu上,带有基本的g ++编译器,没有什么特别的。C++ FIFO奇怪行为

#include <iostream> 
#include <sys/stat.h> 
#include <stdio.h> 
#include <fcntl.h> 
#include <iostream> 
using namespace std; 

int main() { 

    cout << "START" << endl; 

    int fifo; 
    int code; 
    mkfifo("/tmp/FIFO", 666); 
    if ((fifo = open("/tmp/FIFO", O_RDONLY | O_NONBLOCK)) < 0) { 
     perror("open failed"); 
    } 
    else { 
     cout << "open successed" << endl; 
     code = close(fifo); 
     cout << "close: " << code << endl; 
     if ((fifo = open("/tmp/FIFO", O_WRONLY | O_NONBLOCK)) < 0) { 
      perror("reopen failed"); 
     } 
     else { 
      cout << "reopen successed" << endl; 
      code = close(fifo); 
      cout << "close: " << code << endl; 
     } 
    } 

    cout << "END" << endl; 
    return 0; 
} 

我对输出的期望是这样的,因为我关闭它成功:

START 
open successed 
close: 0 
reopen successed 
close: 0 
END 

不过,我得到这个,第二个打开失败。为什么?以及为什么这个愚蠢的错误信息?

START 
open successed 
close: 0 
reopen failed: No such device or address 
END 

我真的想重新打开FIFO写。我想知道上面的代码不起作用的原因。

+0

你能举报open()返回并失败后的errno吗?这可能会给出提示...... – jwismar 2012-07-05 21:50:56

+0

'...(失败时)返回-1,并设置errno以指示错误。“errno”的返回值是什么? – Marlon 2012-07-05 21:51:50

+0

我其实并不知道确切的值,但我们并不需要这个,因为perror会输出消息而不是代码。 (“没有这样的设备或地址”)。 – Daniel 2012-07-06 07:20:45

回答

2

从重新打开中删除O_NONBLOCK标志,或者如果要保留该标志,请连接到已打开供读取的FIFO。 这是正确的行为。

http://linux.die.net/man/7/fifo

进程可以在非阻塞模式下打开一个FIFO。在这种情况下,即使没有人在写入端打开,打开只读也会成功,只有在ENXIO(没有这样的设备或地址)的情况下打开只写才会失败>除非另一端已经打开。

+0

就是这样!我甚至不想在重新开放之前关闭!谢谢! – Daniel 2012-07-06 07:23:06