簡體   English   中英

使用QTextStream以非阻塞方式讀取stdin

[英]using QTextStream to read stdin in a non-blocking fashion

我正在嘗試使用Qt以非阻塞方式讀取stdin流的內容。 當套接字收到一些新數據時,我正在使用QSocketNotifier來提醒我。 通知程序的設置如下所示:

QSocketNotifier *pNot = new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read, this);
connect(pNot, SIGNAL(activated(int)), this, SLOT(onData()));
pNot->setEnabled(true);

onData()插槽如下所示:

void CIPCListener::onData()
{
    qDebug() << Q_FUNC_INFO;
    QTextStream stream(stdin, QIODevice::ReadOnly);

    QString str;

    forever
    {
        fd_set stdinfd;
        FD_ZERO( &stdinfd );
        FD_SET( STDIN_FILENO, &stdinfd );
        struct timeval tv;
        tv.tv_sec = 0;
        tv.tv_usec = 0;
        int ready = select( 1, &stdinfd, NULL, NULL, &tv );
        if( ready > 0 )
        {
            str += stream.readLine();
        }
        else
        {
            break;
        }
    }

    qDebug() << "Recieved data:" << str;
}

如您所見,我正在嘗試使用select()系統調用來告訴我何時我用完了要讀取的數據。 但是,實際上,發生的情況是在我閱讀了第一行文本后,select()調用返回0。 因此,例如,如果我向流程的stdin流中寫入5行文本,則我只會讀取第一行。

可能是什么問題呢?

行緩沖。

默認值為“ \\ n”后刷新。 如果您向進程寫入5行,則插槽將被調用5次。 如果要避免這種情況,則必須調用setbuf(stdin,_IOFBF)。 但是即使那樣也不能保證您可以在一個塊中讀取任意數量的數據。

編輯:最好使用QTextStream :: atEnd()而不是select,因為QTextStream具有自己的內部緩沖區。

我在其他答案中找到了一個示例,該示例幾乎完全適合此問題,並具有完整而簡單的代碼:

https://stackoverflow.com/a/7389622/721929

我用它來實現一個基於QT控制台的應用程序,該應用程序帶有文本菜單供用戶選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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