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