[英]Re-reading from a named pipe when writers come and go
我有一個問題,我必須從命名管道讀取。 我必須處理命名管道的編寫器來去的情況,但我需要在我的應用程序中保持相同的管道打開。
我已在以下代碼中對此進行了總結。
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將阻止,直到出現一個writer。
我已經嘗試使用fcntl設置為BLOCKING模式,但這也不起作用。
我對管道語義的有限理解讓我覺得我需要清除管道上的EOF狀態,以便select現在會阻塞。 但是,我不知道該怎么做。
我把自己放在你的集體智慧上:)馬克。
好的,我想出了一個解決方案,但我對此並不滿意。 如果你問我,這有點像“敲打堅果”。
.....
else if ( nread == 0 )
{
std::cout << "read 0" << std::endl;
FD_ZERO( &rfds );
close( rfd );
if ( (rfd = open( PIPENAME, O_RDONLY | O_NONBLOCK )) < 0 )
{
perror( "re-open" );
break;
}
FD_SET( rfd, &rfds );
nfd = std::max( wfd, rfd ) + 1;
}
else
.....
基本上,我關閉並重新打開管道。
我仍然歡迎更好的解決方案。
在其他一些帖子上找到:
if ( (rfd = open( PIPENAME, O_RDWR | O_NONBLOCK )) < 0 )
即打開RDWR而不是RDONLY似乎工作...
您是否嘗試在非阻塞模式下打開fds,當您的read()
返回EWOULDBLOCK
/ EAGAIN
,在fd上執行一個clearerr()
?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.