阻止调用以读取管道

时间:2016-11-15 11:08:04

标签: c++ qt pipe qt4

我正在使用Qt创建一个显示GUI并接受来自管道输入的小应用程序。

如果没有创建管道(,或者据我所知,如果没有编写器),对fopen的调用会阻塞,甚至认为它是在{{1}之后调用的功能,UI不显示。

如何显示用户界面,然后调用show()及相关代码?只要我的窗口预先显示在屏幕上,我就不在乎fopen会阻塞。

我尝试使用类似fopen的内容,但行为保持不变。

任何提示?谢谢!

的main.cpp

connect(this, SIGNAL(window_loaded), this, SLOT(setupListener()));

metadataWindow.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();
}

1 个答案:

答案 0 :(得分:2)

X是一种基于消息的异步协议。 X显示服务器和X客户端程序不断交换消息。 X客户端程序不只是推送某种虚拟按钮,绘制窗口,并且每天调用它,直到它想要在窗口上更改某些内容。在显示服务器和客户端程序之间没有消息交换的唯一时间是显示器上什么都没有发生。没有鼠标指针移动。没有任何展示活动。

显示窗口的任务依次涉及多个步骤。实际的窗口对象本身就会被创建。所有子窗口都已创建。所有窗口都被映射。映射窗口导致X服务器向客户端程序发送一系列曝光事件,响应于此,客户端程序负责呈现窗口的暴露部分。所有这些都是在X显示服务器和X客户端程序之间交换的数百条消息的序列中完成的。

这就是QApplication::exec()电话的作用。它进入Qt的主事件循环,Qt库相应地处理X显示事件。在事件循环运行之前,不会有任何可见的显示更改。

使用基于事件的基础设施(如X / Qt)时,正确的设计模式也是一种基于事件的方法。你有两个基本选择。

  1. 在新线程中执行阻塞应用程序逻辑,独立于进入Qt事件循环的主执行线程。这可以绕过并且不需要遵循事件驱动的设计模式,并且可以完成普通程序所能完成的任务,而不会打扰Qt。

  2. 也可以为自己的代码使用带有非阻塞文件描述符的事件驱动模型。无法使用fopen()库调用。相反,管道将在非阻塞模式下open(),并且当文件系统管道的另一侧打开时,管道将可选择进行写入。有关详细信息,请阅读open()poll()的手册页。最后阅读Qt的QSocketNotifier类文档,该文档解释了如何让Qt库监视自己文件描述符中的事件,作为其主事件循环的一部分,并调用代码来处理读取和写下它们。

  3. 当然,使用执行线程和套接字通知程序的混合方法也是可能的。重要的是要了解进程应该如何正常工作,并且永远不要编写任何阻止Qt主事件循环的代码。