0

プロセス間通信を使用して、Linux用のC ++で小さなプログラムを書いています。あるプロセスでブロックしない方法で読み取り、別のプロセスで書き込み (ブロック) しようとしたときに問題が発生しました。問題は次のようになります。親が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);

fcntl(fd_co,F_SETFL,0);ノンブロッキングオープンコールの直後に使用することで、これを解決する方法を最終的に見つけました。

man pageを読んだ後、非ブロッキングを読み取り、ブロッキングを書き込みたい場合にファイル記述子のフラグをリセットする必要がある理由の (簡単な) 説明が見つかりませんでした。

誰にも説明がありますか、それとも間違っていますか?

4

1 に答える 1

4

O_NDELAY の「問題」は、使用可能なデータがない場合に read が返され、 -1errno が に設定さEAGAINれることです。したがって、readfor-1と errno の戻り値をテストしてから、再度読み取る必要があります。

FIFOから読み取るものが何もない場合、「修正」はO_NDELAYをリセットするだけで、読み取りブロックが再び作成されます。

こちらもご覧くださいread

戻り
値 ... エラーの場合、-1 が返され、errno が適切に設定されます。

エラー
EAGAINファイル記述子 fd がソケット以外のファイルを参照しており、ノンブロッキング (O_NONBLOCK) とマークされているため、読み取りがブロックされます。
EAGAINまたはEWOULDBLOCK
ファイル記述子 fd がソケットを参照しており、非ブロック (O_NONBLOCK) とマークされているため、読み取りがブロックされます。POSIX.1-2001 では、この場合にいずれかのエラーが返されることを許可しており、これらの定数が同じ値である必要はないため、移植可能なアプリケーションは両方の可能性をチェックする必要があります。

selectあなたのケースでブロッキングが問題である場合は、またはpoll@BasileStarynkevitch が提案したように、の使用を検討することもできます。

于 2013-02-17T18:51:14.683 に答える