【问题标题】:Qt blocking threads and cross-thread communicationQt 阻塞线程和跨线程通信
【发布时间】:2013-07-20 10:21:03
【问题描述】:
我想问一个关于应用程序架构的问题
1。将有用于提供用户交互的主 GUI 线程
2。一个基于 UDP 套接字的接收线程,它将在 UDP 数据包到达时接收它们(希望这是阻塞的。
3. 另一个用于发送基于事件以及周期性 UDP 数据包的线程。
我该如何实现Qt 中的这种架构,基本上我有以下问题:
1. 对于接收线程,我如何使其阻塞?
我知道 readyRead() 信号,我可以将它连接到将处理的某个插槽数据报,但是我如何循环这个以便这个线程永远这样做。
2. 在发送线程中,我可以从 GUI 线程生成一个信号,该信号将由发送线程接收,这里的一个插槽将在套接字上写一些数据,但是当它没有要发送的东西时,这个线程将如何生存,我的意思是循环,轮询什么?
【问题讨论】:
标签:
multithreading
qt
qthread
【解决方案1】:
在辅助线程中使用事件循环。
QThread::exec() 启动线程的事件循环,该循环将一直运行到调用QThread::quit()。那应该可以解决您的“如何等到事情发生”的问题。 QThread::run() 的默认实现只调用 exec(),所以我会这样做。您可以在 main() 方法中设置所有内容,例如对于发件人线程:
//Create UI
MainWindow mainWindow;
mainWindow.show();
//set up sender thread and the `QObject` doing the actual work (Sender)
QThread senderThread;
Sender sender; //the object doing the actual sending
sender.moveToThread(&sender); //move sender to its thread
senderThread.start(); //starts the thread which will then enter the event loop
//connect UI to sender thread
QObject::connect(&mainWindow, SIGNAL(sendMessage(QString)), &sender, SLOT(sendMessage(QString)), Qt::QueuedConnection);
...
const int ret = app.exec(); // enter main event loop
`senderThread.quit();` //tell sender thread to quit its event loop
`senderThread.wait();` //wait until senderThread is done
`return ret;` // leave main
发送者只是一个 QObject 和一个 sendMessage() 插槽进行发送,一个 QTimer 加上另一个插槽用于定期 UDP 包,等等。