【发布时间】:2020-03-03 06:40:13
【问题描述】:
我正在使用 CPP 使用 QTCreator 开发 UI。我的要求是运行一个 UI,并且需要使用函数msgrcv() 不断轮询 linux 消息队列是否有任何数据进入队列。我创建了一个线程来持续监控接收队列消息。在启动和运行上述线程时,UI 卡住了。任何并行运行线程和 UI 的解决方案?
【问题讨论】:
我正在使用 CPP 使用 QTCreator 开发 UI。我的要求是运行一个 UI,并且需要使用函数msgrcv() 不断轮询 linux 消息队列是否有任何数据进入队列。我创建了一个线程来持续监控接收队列消息。在启动和运行上述线程时,UI 卡住了。任何并行运行线程和 UI 的解决方案?
【问题讨论】:
没有看到您的代码就无法判断。但是,如果轮询操作是非阻塞的,那么您实际上不需要线程。您可以改为注册一段代码,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 毫秒调用一次轮询函数。
【讨论】:
connect(&poll_timer, &QTimer::timeout, this, &MainWindow::poll_function);.