2016-12-17 9 views
0

FIFOを1つのプロセスで使用する場合は、両端を開いて1つを閉じた後にFIFOを再利用することはできません。クローズされた終わりを再オープンしようとすると失敗するか、返されたファイル記述子は役に立たない。同じプロセスが同じプロセスでFIFOの両端を使用している場合にFIFOを再オープンできない

この動作を回避することは可能ですか、それともFIFOの両端が開いていても、もはや必要がないことが絶対にわかりますか?ここで

が表示され、FIFOの閉じられた書き込み終了を再開しようとすると、いくつかのテストコードです:ここで

#include <iostream> 
#include <cstdio> 
#include <errno.h> 
#include <fcntl.h> 
#include <limits.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 

using namespace std; 

int main(int argc, const char **argv) 
{ 
     cout << "Creating an instance of a named pipe..." << endl; 
     mode_t prevMask = umask(0); 
     if (mknod("my_pipe", S_IFIFO | 0666, 0)) 
     return -1; 
     umask(prevMask); 

     cout << "Opening Read end..." << endl; 
     int fdM = open("my_pipe", O_RDONLY | O_NONBLOCK); 
     if (fdM == -1) 
     return -1; 

     cout << "Opening Write end..." << endl; 
     int fdS = open("my_pipe", O_WRONLY | O_NONBLOCK); 
     if (fdS == -1) 
     return -1; 

     cout << "Sending data to pipe..." << endl; 
     const char *data = "Hello my friend!"; 
     ssize_t NbOfBytesWritten = write(fdS, data, strlen(data)); 
     if (NbOfBytesWritten < 0) 
     return -1; 
     cout << "Number of bytes sent: " << NbOfBytesWritten << endl; 

     cout << "Closing Write end..." << endl; 
     if (close(fdS)) 
     return -1; 

     cout << "Reopening Write end..." << endl; 
     fdS = open("my_pipe", O_WRONLY | O_NONBLOCK); 
     if (fdS == -1) 
     { 
     cout << "open() - failed("<< errno << "): " << strerror(errno) << '.'; 
     remove("my_pipe"); 
     return -1; 
     } 

     cout << "Sending some more data to pipe..." << endl; 
     data = "What's up?"; 
     NbOfBytesWritten = write(fdS, data, strlen(data)); 
     if (NbOfBytesWritten < 0) 
     return -1; 
     cout << "Number of bytes sent: " << NbOfBytesWritten << endl; 

     cout << "Reading data from pipe..." << endl; 
     char buff[128]; 
     ssize_t numBytesRead = read(fdM, buff, 127); 
     if (NbOfBytesWritten < 0) 
     return -1; 
     buff[numBytesRead] = '\0'; // null terminate the string 
     cout << "Number of bytes read: " << numBytesRead << endl; 
     cout << "Message: " << buff << endl; 

     cout << "Closing Write end..." << endl; 
     if (close(fdS)) 
     return -1; 

     cout << "Closing Read end..." << endl; 
     if (close(fdM)) 
     return -1; 

     cout << "Deleting pipe..." << endl; 
     if (remove("my_pipe")) 
     return -1; 

    return 0; 
} 

が出力されます:

Creating an instance of a named pipe... 
Opening Read end... 
Opening Write end... 
Sending data to pipe... 
Number of bytes sent: 16 
Closing Write end... 
Reopening Write end... 
open() - failed(6): No such device or address. 

私も再度開くしようとしているようなコードをテストしましたクローズドリードエンド(書き込み終了時)。この場合、open()関数は成功しますが、open()によって返されたファイル記述子を使用したread()関数は失敗します。 send error on send。 (70)

編集:

私はCYGWINを使用しています。

+0

これはLinux上でエラーなしで実行されます。 – PSkocik

+0

両端を開いたままにする必要があります。すべての書き込み終了が閉じられると、リーダーはEOFを取得します。また、読み込みの終了がすべて終了すると、書き込もうとすると「EPIPE」を取得します。 – Barmar

+0

@Barmar - 質問は次のとおりです。「なぜFIFOの終わりを再び開くことができないのですか?」両端に接続されていないFIFOへの書き込み、またはFIFOからの読み出しの影響ではありません。 – Guett31

答えて

1

あなたのコードはLinux上で問題なく動作します。私はあなたが実行している問題は、CYGWINの名前付きパイプがうまく動作せず、POSIXのセマンティクスに従わないということです。 FIFO (named pipe) is broken on Cygwinを参照してください。同じ問題がある可能性があります。

関連する問題