using QTextStream to read stdin in a non-blocking fashion

落爺英雄遲暮 提交于 2019-11-30 03:26:22

问题


Using Qt, I'm attempting to read the contents of the stdin stream in a non-blocking fashion. I'm using the QSocketNotifier to alert me when the socket has recieved some new data. The setup for the notifier looks like this:

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

The onData() slot looks like this:

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

As you can see I'm attempting to use the select() system call to tell me when I've run out of data to read. However, in practise what is happening is the select() call returns 0 after I've read the first line of text. So, for example, if I write 5 lines of text to the process's stdin stream, I only ever read the first line.

What could be the problem?


回答1:


Line buffering.

Default is flushing after a "\n". If you write 5 lines to your process, your slot gets called 5 times. If you want to avoid that, you have to call setbuf(stdin, _IOFBF). But even then it is not guaranteed you can read arbitrarily large amounts of data in one chunk.

Edit: It would probably better to use QTextStream::atEnd() instead of select, since QTextStream has its own internal buffers.




回答2:


I've found and example in other answer that fits almost to this question and with complete and simple code:

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

I've used it to implement a QT console based app with a textual menu to choose on user selection.



来源:https://stackoverflow.com/questions/1271784/using-qtextstream-to-read-stdin-in-a-non-blocking-fashion

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!