簡體   English   中英

當作家來來往往時,從一個命名管道重新讀取

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM