如何并行运行 Qt GUI 和 Linux 消息队列接收线程?

Posted

技术标签:

【中文标题】如何并行运行 Qt GUI 和 Linux 消息队列接收线程?【英文标题】:How to run Qt UI and Linux message queue reception thread in parellel? 【发布时间】:2020-03-03 06:40:13 【问题描述】:

我正在使用 CPP 使用 QTCreator 开发 UI。我的要求是运行一个 UI,并且需要使用函数msgrcv() 不断轮询 linux 消息队列是否有任何数据进入队列。我创建了一个线程来持续监控接收队列消息。在启动和运行上述线程时,UI 卡住了。任何并行运行线程和 UI 的解决方案?

【问题讨论】:

【参考方案1】:

没有看到您的代码就无法判断。但是,如果轮询操作是非阻塞的,那么您实际上不需要线程。您可以改为注册一段代码,Qt 的事件循环将在每次 UI 事件循环迭代时运行。你使用 0ms QTimer 来做到这一点:

void poll_function();

// ...

QTimer poll_timer;
QObject::connect(&poll_timer, &QTimer::timeout, poll_function);
poll_timer.start();

当然,在上面的示例代码中,一旦poll_timer 超出范围,poll_function() 将停止被调用。在您的真实代码中,您应该使用QTimer,只要您需要,它就会一直存在。可能应该是您的 QApplication 子类的数据成员。

如果poll_function() 阻塞,那么这种方法将不起作用,因为它会阻塞 UI。所以你应该确保告诉msgrcv()不要阻止。来自man page:

如果没有请求类型的消息可用并且在 msgflg 中没有指定 IPC_NOWAIT,则调用进程被阻塞

因此,请确保在调用 msgrcv() 时将 IPC_NOWAIT 包含在 msgflg 标志中。

如果轮询每个 UI 事件循环迭代的开销太大,那么您可以改为设置一个以毫秒为单位的正常超时间隔:

poll_timer.setInterval(500);

这将每 500 毫秒调用一次轮询函数。

【讨论】:

但我无法访问 poll 函数中的任何 MainWINdow 类函数。任何访问解决方案??? @Winner 只需将 poll 函数设为 MainWindow 的成员函数,然后连接到该函数即可。例如在 MainWindow 构造函数中:connect(&poll_timer, &QTimer::timeout, this, &MainWindow::poll_function);.

以上是关于如何并行运行 Qt GUI 和 Linux 消息队列接收线程?的主要内容,如果未能解决你的问题,请参考以下文章

在VNC上运行Qt GUI应用程序导致分段错误,并显示错误消息

如何在 linux 中编写和加载 GUI? [关闭]

非GUI-Qt程序运行后显示Console(简单好用)

在Linux中的帧缓冲区上运行Qt GUI应用程序

在 Linux ARM 上编译不支持 GUI 的 Qt5

如何在 linux 中显示来自 bash 脚本的 GUI 消息框?