Tho*_*omi 8 c++ qt stdin blocking
使用Qt,我试图以非阻塞的方式读取stdin流的内容.当套接字收到一些新数据时,我正在使用QSocketNotifier来提醒我.通知程序的设置如下所示:
QSocketNotifier *pNot = new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read, this);
connect(pNot, SIGNAL(activated(int)), this, SLOT(onData()));
pNot->setEnabled(true);
Run Code Online (Sandbox Code Playgroud)
该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;
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在尝试使用select()系统调用来告诉我何时我的数据用完了.但是,在实践中发生的事情是,在我读完第一行文本后,select()调用返回0.因此,例如,如果我向进程的stdin流写入5行文本,我只读过第一行.
可能是什么问题呢?
行缓冲。
默认值是在“\n”之后刷新。如果您向进程写入 5 行,则您的槽会被调用 5 次。如果你想避免这种情况,你必须调用 setbuf(stdin, _IOFBF)。但即便如此,也不能保证您可以在一个块中读取任意大量的数据。
编辑:最好使用 QTextStream::atEnd() 而不是 select,因为 QTextStream 有自己的内部缓冲区。