2015-10-19 18 views
1

如果我想將數據寫入到遠程側,等待它的答案,我至少需要waitForReadyRead。但在調用之前,是否需要使用waitForBytesWritten手動刷新輸出隊列,還是Qt會自動爲我寫入寫入隊列?我正在同步(阻塞),因此在這個函數中我無法使用事件循環或本地事件循環。不會了QIODevice :: waitForReadyRead隱含刷新輸出隊列(waitForBytesWritten)?

當使用std::cin時,我們可以確定以前寫入的字節std::cout將被刷新。這是類似的情況 - 它是否也適用於Qt套接字?

回答

0

如果你看一下source code,是一個抽象基類,QIODevice中確實很少在waitForReadyRead和它給繼承類的實現:

bool QIODevice::waitForReadyRead(int msecs) 
{ 
    Q_UNUSED(msecs); 
    return false; 
} 

它適用於Qt的插座藏漢?

正如你說,你是同步操作,我想你已經選擇了這是有原因的,並都知道,在主線程,任何存在的GUI將對waitForReadyRead在通話過程中凍結。通常,QIODevice的異步使用是首選,Qt是一個事件驅動的框架。

然而,Qt docs狀態:

QIODevice中的某些亞類,如和與QTcpSocket QProcess中,是異步的。

因此,如果您的QIODevice是如一個與QTcpSocket插座,然後不,你不應該需要調用waitForReadyRead時要調用waitForBytesWritten

在非同步裝置的情況下,這將是必需的。

+0

嗯,我不明白的結論,「因此,如果你的QIODevice是如一個與QTcpSocket插座,然後不,你不應該需要調用waitForReadyRead時要調用waitForBytesWritten」。什麼阻止Qt只是輪詢或選擇套接字讀取文件描述符以獲取新字節並填充其讀取隊列?爲什麼異步意味着我必須刷新字節? –

+0

我的印象是,在這種情況下「異步」意味着調用寫入和讀取不會直接訪問設備,而是讀取和寫入緩衝區,只有在返回事件循環或調用時才寫入或讀取其中一個等待功能? –

+0

也許我誤解了你的問題,如果是這樣,請糾正我。就目前而言,我知道它意味着它是在一個單獨的線程上處理的,所以經常在主線程中調用waitForReadyRead(這是一個阻塞調用)將不會阻塞設備的寫入過程,例如與QTcpSocket。 – TheDarkKnight

0

我後來問了Thiago Macieira(QtCore維護者)關於這個問題,他回答說,對於QAbstractSocket,waitForBytesWritten和waitForReadyRead都會寫入待處理字節,這些字節位於qt緩衝區中,等待切換到操作系統。

,做僅等待要寫入的字節和僅在之後的應用程序讀取進來的字節可以潛在死鎖,如果遠程站點被阻塞的,因爲等待其他(本地)側讀取數據。由於遠端阻塞,它不能讀取本地發送的數據。因此,如果本地方寫太多以至於阻塞,每個方都會等待另一方讀取其數據和死鎖。

因此兩者bytesWritten和readyRead等待功能的過程既qt的讀和qt寫緩衝器。 waitForBytesWritten甚至可能會發出readyRead信號,這是我沒有想到的。所以waitForBytesWritten調用本質上是多餘的,可以刪除。