浅谈 Qt 子线程 信号队列
创始人
2024-08-02 02:50:43
0

Qt子线程 信号队列是本文要介绍的内容,声明:以下纯属个人理解,看到的就当错的看。对 Qt 的多线程编程没有深究,只了解了基本的用法,够我用就行了。

之所以写这篇文章是因为前几天遇到一个疑问:如果其他几个线程同时向一个线程发signal,而这个线程没有自己的事件循环,那是不是会丢失signal呢?

下面是我总结的两种子线程的工作方式

1、让子线程进入事件循环,这样的话多余的signal就会进入该线程的事件队列,不会丢失。问题是这时子线程的槽函数都是在该子线程对象所在的线程(很可能是主线程)执行,这样似乎失去了多线程的意义。

  1. void run()  
  2. {  
  3.     exec();  
  4. }  
  5. void slot1();  //处理工作  
  6. void slot2();  //处理工作 

2、子线程没有事件循环,直接在run里处理工作,主线程可通过信号连接到该子线程的槽来控制flag,从而控制子线程的暂停和继续。但是,如果还有另外几个线程不时地向通过slot2()给somarg赋值的话,即使给slot2()加了锁保证了不会被同时赋值,但那些同时进入的赋值信号没有队列可进,这样会不会就丢失了呢

  1. void run()  
  2. {  
  3.     while(1)  
  4.     {  
  5.     while(flag)  
  6.     {  
  7.         dosomething(somarg);  
  8.     }  
  9.     }  
  10. }  
  11. void slot1();  //控制flag  
  12. void slot2();  //给somarg赋值 

经试验,虽然第一种办法不需要exec()进入事件循环也可以触发槽们在调用这个线程对象的线程工作,但是这样无法保证同时传进去的信号不会丢失;加上exec()后,子线程进入事件循环,不会马上结束,并且会有事件队列,这样可以保证信号不会丢失。唯一的缺点就是这些槽不工作在子线程。

拟对策:

建立一个队列线程,CQueueThread,这个线程进入自己的事件循环,在这个类中有其它线程的对象作为成员变量,这些线程则没有各自的事件队列,直接在run中死循环工作,主线程信号连接到CQueueThread的槽来控制其他线程开始工作,这样信号会进入事件队列不会丢失,而那些死循环的繁杂工作则各自在各自的线程中运行。

这个CQueueThread可以用主线程代替(主线程必然是有事件循环的),主线程中有个槽作缓冲用,接收来自各方的命令,再鱼贯发往目标线程。

"run()开的才是新线程,QThread的构造函数以及其他成员都在你的主线程中。"

小结: Qt 子线程 信号队列的内容介绍完了,希望本文对你有所帮助。关于线程的更多资料,请参考编辑推荐。

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...