并行运行多个QEventLoops(用于QtNetwork)

Run multiple QEventLoops in parallel (for QtNetwork)

本文关键字:用于 QtNetwork QEventLoops 运行 并行      更新时间:2023-10-16

我尝试扩展一个在Ubuntu/Linux Desktop下运行的旧程序,并支持Qt网络。与这些库进行局域网通信需要运行QEventLoop的.exec()才能真正开始工作(即:接受连接,接收,发送等)。

问题所在

好吧,问题是我不知道这个事件循环在主程序中的位置,因为我模糊地知道它的设计,所以我更喜欢尽可能独立的解决方案。

我的想法

我已经检查过我不需要主QEventLoop,并且可以仅为网络(即嵌套)制作另一个。不幸的是,我无法弄清楚如何并行运行两个循环,因为我的程序在嵌套.exec()处停止,因此主程序也处于停止状态。

所以我的主要意图实际上是用Qt网络扩展主程序,我也对其他解决方案持开放态度。

如果您需要运行 2 个独立的事件循环,我建议使用 QThread。

主程序是交互式的吗?如果是,那么它很可能运行 glib 主事件循环。Qt在Linux上使用相同的事件循环,因此您无需在代码中调用exec()。通过创建 QEventLoop 实例、向其发布退出调用并对其进行exec(),仅启动事件循环一次。然后将控制权返回给主程序。您的代码仍将在事件到达时运行(计时器超时、网络数据包到达等)。

使用Qt获得的原生事件循环集成的美妙之处在于,如果其他人已经在旋转循环,则无需执行主要exec()

因此,以下是Linux上GTK应用程序的Qt插件可能的样子:

extern "C" void pluginInit() {
  new QApplication;
  QEventLoop loop;
  QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection);
  loop.exec();
}
extern "C" void pluginDestroy() {
  delete qApp;
}

一旦插件用户调用pluginInit,他们就可以调用插件中使用Qt的任何函数,并且事件将由调用应用程序的事件循环正确处理。

与线程相比,我更喜欢这样的解决方案,因为它通常听起来更稳定。

如果线程对你来说不稳定,那么你做得不对。网络支持将在专用线程上运行良好。这可能是第二个线程为数不多的合法用途之一,因为这样您的网络数据处理就不会因用户空间渲染器和合成器将您在屏幕上看到的内容放在一起而延迟。