2012-07-05 206 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