簡體   English   中英

阻止調用以讀取管道

[英]Blocking call to read a pipe

我正在使用Qt創建一個顯示GUI並接受管道輸入的小型應用程序。

如果未創建管道( 或者據我了解,如果沒有writer ),則將調用fopen塊,甚至認為應該在show()函數之后調用它,否則不會顯示UI。

如何顯示UI,然后調用fopen和相關代碼? 我不在乎fopen阻塞,只要我的窗口事先在屏幕上即可。

我已經嘗試使用諸如connect(this, SIGNAL(window_loaded), this, SLOT(setupListener())); 但行為保持不變。

有什么提示嗎? 謝謝 !

main.cpp中

#include <QApplication>

#include "metadataWindow.h"

#include <sys/time.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    metadataWindow window;
    window.showFullScreen();
    window.setupListener();

    return app.exec();
}

metadataWindow.cpp

metadataWindow::metadataWindow(QWidget *parent) : QWidget(parent)
{
    this->setupUI(); // not shown here, but just basic QLabel stuff
}

void metadataWindow::setupListener()
{
    const char *metadata_file = "/tmp/my-pipe-file";

    // vvvvv This here is blocking vvvvvv
    FILE *fd = fopen(metadata_file, "r");

    pipe = new QTextStream(fd);

    streamReader = new QSocketNotifier(fileno(fd), QSocketNotifier::Read, qApp);
    QObject::connect(streamReader, SIGNAL(activated(int)), this, SLOT(onData()));
    streamReader->setEnabled(true);
}

X是異步的,基於消息的協議。 X顯示服務器和X客戶端程序正在不斷交換消息。 X客戶端程序不僅要按某種虛擬按鈕,繪制其窗口,然后每天調用它,直到它想要更改窗口上的某些內容為止。 顯示服務器和客戶端程序之間沒有消息交換的唯一時間是顯示器上絕對沒有任何反應。 沒有鼠標指針移動。 沒有任何顯示活動。

顯示窗口的任務依次涉及多個步驟。 實際的窗口對象本身已創建。 將創建所有子窗口。 所有窗口都被映射。 映射窗口會導致X服務器向客戶端程序發送一系列曝光事件,作為響應,客戶端程序負責渲染窗口的暴露部分。 所有這些都是在X顯示服務器和X客戶端程序之間交換數百條消息的序列來完成的。

這就是QApplication::exec()調用所做的。 它進入Qt的主事件循環,Qt庫相應地處理X個顯示事件。 在事件循環運行之前,不會有任何可見的顯示更改。

當與基於事件的基礎架構(例如X / Qt)一起使用時,正確的設計模式也是基於事件的方法。 您有兩個基本選擇。

  1. 在新線程中執行阻塞應用程序邏輯,而與進入Qt事件循環的主執行線程無關。 這就繞過並避開了遵循事件驅動設計模式的需要,並使得無需擔心Qt就可以做普通程序幾乎可以做的事情。

  2. 對於您自己的代碼,也請使用帶有非阻塞文件描述符的事件驅動模型。 不能使用fopen()庫調用。 取而代之的是,該管道將在非阻塞模式下被open() ed,並且當文件系統管道的另一側被打開時,該管道將是可選擇進行寫入的。 閱讀有關open()poll()的手冊頁,以獲取更多信息。 最后閱讀Qt關於QSocketNotifier類的文檔,該文檔解釋了如何讓Qt庫還監視您自己的文件描述符中的事件,作為其主事件循環的一部分,並調用您的代碼來處理讀取和寫入它們的任務。

當然,也可以同時使用執行線程和套接字通知程序的混合方法。 重要的一點是要了解該流程應如何正確運行,並且永遠不要編寫任何會阻塞Qt主事件循環的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM