У меня проблема с чтением из именованного канала. Я должен разобраться с ситуацией, когда пишущие в именованный канал приходят и уходят, но мне нужно держать один и тот же канал открытым во всех моих приложениях.
Я резюмировал это в следующем коде.
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, иначе открытие будет блокироваться, пока не появится писатель.
Я пытался использовать fcntl, чтобы установить режим BLOCKING, но это тоже не работает.
Мое ограниченное понимание семантики канала заставляет меня думать, что мне нужно очистить состояние EOF на канале так, чтобы select теперь блокировал. Однако я не знаю, как это сделать.
Я бросаюсь на твою коллективную мудрость :)
Марк.