【问题标题】:Run multiple QEventLoops in parallel (for QtNetwork)并行运行多个 QEventLoops(用于 QtNetwork)
【发布时间】:2016-03-02 10:40:43
【问题描述】:

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

问题

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

我的想法

我已经检查过我不需要 main-QEventLoop,并且可以为网络创建另一个(即嵌套)。不幸的是,我不知道如何并行运行这两个循环,因为我的程序在嵌套的.exec() 处停止,因此主程序也暂停了。

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

【问题讨论】:

  • @KubaOber 是的,你完全正确。如果您将此作为答案,我会将其标记为解决方案。

标签: c++ qt parallel-processing qtnetwork qeventloop


【解决方案1】:

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

【讨论】:

  • 是否保证我的传入连接将被接受(通过信号/插槽过程),或者可能是由于当时线程未运行而导致请求丢失?
  • 你必须确保线程正在运行。如果线程未运行,则不会触发线程中“生活”的对象。出于这个原因,您应该创建线程,将对象移动到线程并启动线程。然后你就可以建立你的连接了。
【解决方案2】:

主程序是交互式的吗?如果是,那么它很可能会运行 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的任何函数,并且事件将被调用应用程序的事件循环正确处理。

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

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

【讨论】:

  • 像魅力一样工作。我从未想过使用invokeMethod(...)。非常感谢
猜你喜欢
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
  • 2013-10-10
  • 2018-03-03
  • 2023-03-22
  • 2012-03-18
相关资源
最近更新 更多