Domanda

Utilizzando Qt, sto cercando di leggere il contenuto del flusso stdin in un modo non-blocking. Sto utilizzando la QSocketNotifier per avvisare me quando il socket ha ricevuto alcuni nuovi dati. L'impostazione per il notificante è simile al seguente:

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

Lo slot onData() assomiglia a questo:

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;
}

Come potete vedere sto cercando di utilizzare la chiamata di sistema select () per dirmi quando ho esaurito di dati da leggere. Tuttavia, in pratica ciò che sta accadendo è la select () chiamata restituisce 0 dopo che ho letto la prima riga di testo. Così, per esempio, se scrivo 5 linee di testo al flusso stdin del processo, ho sempre e solo letto la prima riga.

Quale potrebbe essere il problema?

È stato utile?

Soluzione

Linea buffering.

default è vampate di calore, dopo un "\ n". Se si scrive 5 linee al vostro processo, lo slot viene chiamato 5 volte. Se si vuole evitare che, si deve chiamare setbuf (stdin, _IOFBF). Ma anche in questo caso non è garantito che si può leggere arbitrariamente grandi quantità di dati in un unico pezzo.

Modifica: Sarebbe probabilmente meglio utilizzare QTextStream :: atend () invece di selezionare, dal momento QTextStream ha i suoi buffer interni

.

Altri suggerimenti

ho trovato e l'esempio in altra risposta che si adatta quasi a questa domanda e con il codice completo e semplice:

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

L'ho usato per implementare un'applicazione console basata QT con un menu testuale di scegliere sulla selezione dell'utente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top