名前付きパイプから読み取らなければならないという問題があります。名前付きパイプへのライターが行き来する状況に対処する必要がありますが、アプリケーション全体で同じパイプを開いたままにしておく必要があります。
これを次のコードにまとめました。
int main( int c, char *v[] )
{
int rfd;
if ( (rfd = open( PIPENAME, O_RDONLY | O_NONBLOCK )) < 0 )
{
perror( "open" );
return 1;
}
char buffer[ 1024000 ];
// used to give select an upper bound on number of fds
int nfd = rfd + 1;
fd_set rfds;
FD_ZERO( &rfds );
FD_SET( rfd, &rfds );
while( true )
{
int nr = select( nfd, &rfds, NULL, NULL, NULL );
if ( nr < 0 )
{
perror( "select" );
break;
}
if ( FD_ISSET( rfd, &rfds ) )
{
//std::cout << "RFD SET" << std::endl;
// Ok, we have data we can read
int nread = read( rfd, buffer, sizeof( buffer ) );
if ( nread < 0 )
{
perror( "read" );
break;
}
else if ( nread == 0 )
{
std::cout << "read 0" << std::endl;
}
else
{
std::cout << "read " << nread << " bytes" << std::endl;
}
}
}
close( rfd );
return 0;
}
私が抱えている問題は、最初のプロセスが名前付きパイプに書き込み、それが終了した後、プログラムが選択をブロックしないことです。事実上、rfdが設定されており、読み取りはタイトループで読み取られたゼロバイトを返します。
rfdをNON_BLOCKINGモードにする必要があります。そうしないと、ライターが表示されるまでopenがブロックされます。
fcntlを使用してBLOCKINGモードに設定しようとしましたが、それも機能しません。
パイプのセマンティクスについての私の限られた理解は、selectがブロックされるようにパイプのEOF状態をクリアする必要があると思います。しかし、これを行う方法がわかりません。
私はあなたの集合的な知恵に身を投じます:)マーク。