并行运行多个qeventloop(对于QtNetwork)

时间:2022-02-27 21:35:07

I try to extend an old program that runs under Ubuntu/Linux Desktop with a Qt-network support. Having a LAN communication with these libraries needs to run the .exec() of the QEventLoop to really start working (i.e.: accept connections, receive, send, etc.)

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

The problem

这个问题

Well the problem is I don't know where this event loop is in the main program and because I vaguely know about it's design I prefer a solution that is as indipendent as possible.

问题是,我不知道这个事件循环在主程序的什么地方,因为我模糊地知道它的设计,我更倾向于一个尽可能不受影响的解决方案。

My idea

我的想法

I already checked I don't need the main-QEventLoop, and it's alright to make another one just for the networking (i.e. nesting). Unfortunately I can't figure out how to run both loops in parallel, since my program stops at the nested-.exec() and so the main program is on halt too.

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

So my main intention is actually to extend the main program with a Qt-Networking, I'm open for other solutions too.

因此,我的主要目的是通过qt网络扩展主程序,我也为其他解决方案开放。

2 个解决方案

#1


1  

Is the main program interactive? If it is, then likely it runs the glib main event loop. Qt uses the same event loop on Linux, so you don't need to call exec() in your code. Prime the event loop only once by creating an instance of QEventLoop, posting a quit call to it, and exec() ing it. Then return control to the main program. Your code will still run as events arrive (timers time out, network packets arrive, etc.).

主程序是交互式的吗?如果是,那么它可能运行glib主事件循环。Qt在Linux上使用相同的事件循环,因此您不需要在代码中调用exec()。只通过创建QEventLoop的一个实例来启动事件循环,然后发布一个退出调用,然后执行它。然后将控制返回到主程序。当事件到达时,您的代码仍然会运行(计时器超时,网络数据包到达等)。

The wonderful thing about native event loop integration that you get with Qt is that you don't need to do the main exec() if someone else is spinning the loop already.

与Qt有关的本地事件循环集成的奇妙之处在于,如果其他人已经在旋转这个循环,那么就不需要执行主exec()。

So, here's how a Qt plugin to a GTK application on Linux might look like:

所以,这是一个Qt插件在Linux上的GTK应用程序的样子:

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

extern "C" void pluginDestroy() {
  delete qApp;
}

Once the plugin user calls pluginInit, they can invoke any function in your plugin that uses Qt, and the events will be properly processed by the invoking application's event loop.

一旦插件用户调用pluginInit,他们就可以在你的插件中调用任何使用Qt的函数,并且事件将通过调用应用程序的事件循环得到适当的处理。

I'd prefer such a solution compared to threading, since it sounds more stable in general.

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

If threading is unstable for you, you're not doing it right. Networking support will run great on a dedicated thread. It's probably one of the few legitimate uses for a second thread, since that way your network data processing won't be delayed by the sweet time the userland renderer and compositor takes to put together what you see on the screen.

如果线程对你来说是不稳定的,那你就做错了。网络支持将在专用线程上运行良好。它可能是第二个线程的少数合法用途之一,因为这样,您的网络数据处理就不会被userland renderer和compositor用来组装您在屏幕上看到的内容的甜蜜时间所延迟。

#2


2  

I would suggest to use a QThread if you are in need of running 2 independent event loops.

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

#1


1  

Is the main program interactive? If it is, then likely it runs the glib main event loop. Qt uses the same event loop on Linux, so you don't need to call exec() in your code. Prime the event loop only once by creating an instance of QEventLoop, posting a quit call to it, and exec() ing it. Then return control to the main program. Your code will still run as events arrive (timers time out, network packets arrive, etc.).

主程序是交互式的吗?如果是,那么它可能运行glib主事件循环。Qt在Linux上使用相同的事件循环,因此您不需要在代码中调用exec()。只通过创建QEventLoop的一个实例来启动事件循环,然后发布一个退出调用,然后执行它。然后将控制返回到主程序。当事件到达时,您的代码仍然会运行(计时器超时,网络数据包到达等)。

The wonderful thing about native event loop integration that you get with Qt is that you don't need to do the main exec() if someone else is spinning the loop already.

与Qt有关的本地事件循环集成的奇妙之处在于,如果其他人已经在旋转这个循环,那么就不需要执行主exec()。

So, here's how a Qt plugin to a GTK application on Linux might look like:

所以,这是一个Qt插件在Linux上的GTK应用程序的样子:

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

extern "C" void pluginDestroy() {
  delete qApp;
}

Once the plugin user calls pluginInit, they can invoke any function in your plugin that uses Qt, and the events will be properly processed by the invoking application's event loop.

一旦插件用户调用pluginInit,他们就可以在你的插件中调用任何使用Qt的函数,并且事件将通过调用应用程序的事件循环得到适当的处理。

I'd prefer such a solution compared to threading, since it sounds more stable in general.

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

If threading is unstable for you, you're not doing it right. Networking support will run great on a dedicated thread. It's probably one of the few legitimate uses for a second thread, since that way your network data processing won't be delayed by the sweet time the userland renderer and compositor takes to put together what you see on the screen.

如果线程对你来说是不稳定的,那你就做错了。网络支持将在专用线程上运行良好。它可能是第二个线程的少数合法用途之一,因为这样,您的网络数据处理就不会被userland renderer和compositor用来组装您在屏幕上看到的内容的甜蜜时间所延迟。

#2


2  

I would suggest to use a QThread if you are in need of running 2 independent event loops.

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