gpt4 book ai didi

c++ - 阻塞读取管道的调用

转载 作者:行者123 更新时间:2023-11-30 03:36:34 27 4
gpt4 key购买 nike

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

如果管道没有创建(或者,据我所知,如果没有编写器),对 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();
}

元数据窗口.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 是一种异步的、基于消息的协议(protocol)。 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 主事件循环的代码。

关于c++ - 阻塞读取管道的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40608306/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com