Qt 主线程阻塞导致所有信号槽均阻塞,用什么方法可以解决这个问题呢?

lusirking 2016-07-21 10:42:37
用Qt写的基于对话框的tcp程序,分三个线程,负责界面显示主线程、负责tcp接收及报文处理的接收线程以及负责tcp发送的发送线程,程序的执行流程大概是这样的:接收线程收到报文对报文进行解析并组织返回包,处理完毕以信号槽的方式将报文传递给发送线程进行发送,现在的问题是当我鼠标左键长时间单击对话框的关闭按钮时会导致主线程阻塞,而此时接收线程和发送线程之间的信号槽也阻塞了,即接收线程无法将信号发送到发送线程,请问各位用什么办法可以避免这种矛盾的产生呢?另外,界面初始化时也会造成返回报文丢失的情况。
...全文
4629 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
mantis_4545 2017-12-27
  • 打赏
  • 举报
回复 1
tcp类放在支线程离new, 收到消息后推到队列里, 然后通过信号通知主线程去队列里取
Li Xiaolin 2017-12-09
  • 打赏
  • 举报
回复
信号槽的实时性本来就不高,在实时系统中应该避免信号槽 通过收发线程之间共享一个缓存的方法才是合适的做法,收线程采取阻塞式接收,收到数据保存到缓存。而发线程就不停地从缓存中读取数据处理并发送。 另外,你可以看看你现在是不是真的是多线程,有没有用对Qt的多线程。因为主线程阻塞并不会影响其他线程之间的信号槽通信!
走好每一步 2017-12-01
  • 打赏
  • 举报
回复
要moveThread的,不然子线程和主线程共用一个信号槽!
张小飞Official 2017-12-01
  • 打赏
  • 举报
回复
楼上说的对,一定要moveThread,而且最后一个connect不要设置为Qt::DirectConnection这样线程不安全。至于原因不为啥,这是Qt的connect机制啊。官方文档说的很明白
Acuity. 2017-11-27
  • 打赏
  • 举报
回复
引用 2 楼 lusirking 的回复:
之前也考虑过这种方式,但是这样实时性会有所下降,因为我在检测到队列内无数据时需要sleep一下,如果不sleep又会导致cpu占用率居高不下。程序报文吞吐量较大且实时性要求比较高,所以才采用了信号槽当有报文需要发送时马上通知发送端发送
信号量等待采用阻塞的方式,无数据是直接挂起当前线程了,还sleep什么?
dashumak 2017-11-26
  • 打赏
  • 举报
回复
连接不同线程的信号槽将第五个参数设为Qt::QueuedConnection,你试一下,槽函数是不是在正确的线程里调用。 试着加断点,如果槽函数不响应的话。你检查一下线程的事件循环,一定是哪里阻塞了,参考一下这个: https://www.cnblogs.com/hdjjun/p/3261984.html
lusirking 2016-07-22
  • 打赏
  • 举报
回复
引用 9 楼 tyousi 的回复:
我觉得楼主不用把注意力一直放在信号槽上,线程之间传递消息也可以使用event,可以查查QApplication::postEvent的使用方法
发送事件的话,要带报文传递,好实现吗?
lusirking 2016-07-21
  • 打赏
  • 举报
回复
其实我的问题主要就是,对于Qt多线程,线程间的信号槽实际是归属于主线程的,当主线程出现阻塞就导致了线程间的信号槽阻塞,不知道有没有什么好的方法规避这个问题……
lusirking 2016-07-21
  • 打赏
  • 举报
回复
之前也考虑过这种方式,但是这样实时性会有所下降,因为我在检测到队列内无数据时需要sleep一下,如果不sleep又会导致cpu占用率居高不下。程序报文吞吐量较大且实时性要求比较高,所以才采用了信号槽当有报文需要发送时马上通知发送端发送
qt_dog 2016-07-21
  • 打赏
  • 举报
回复
可以通过共享变量进行TCP报文在两个线程之间的传输, 即申请一块队列内存,接收线程不停的入队,发送线程不停的出队, 从而与主线程脱离开来。
tyousi 2016-07-21
  • 打赏
  • 举报
回复
我觉得楼主不用把注意力一直放在信号槽上,线程之间传递消息也可以使用event,可以查查QApplication::postEvent的使用方法
lusirking 2016-07-21
  • 打赏
  • 举报
回复
请教下:连接不同线程的信号槽将第五个参数强制设为Qt::DirectConnection,如下 connect(mp_HMIRecvThread, SIGNAL(hbAckPackisReady(QByteArray)), mp_HMISendThread, SLOT(pushAckPackIntoBuf(QByteArray)),Qt::DirectConnection); 这样会不会有什么隐患呢?为什么这样是线程不安全的呢?
lusirking 2016-07-21
  • 打赏
  • 举报
回复
请教下:连接不同线程的信号槽将第五个参数强制设为Qt::DirectConnection,如下 connect(mp_HMIRecvThread, SIGNAL(hbAckPackisReady(QByteArray)), mp_HMISendThread, SLOT(pushAckPackIntoBuf(QByteArray)),Qt::DirectConnection); 这样会不会有什么隐患呢?
lusirking 2016-07-21
  • 打赏
  • 举报
回复
引用 5 楼 u010111033 的回复:
共享的数据你可以单独写一个辅助类,里面写静态的数据:class myHelp 里面关联:static QString str = “ ”,先定义为空,进行赋值后:myHelp::str 即可为两个线程同时使用,数据也不会更改
可否说的详细点?没太明白你的意思
Little柯南 2016-07-21
  • 打赏
  • 举报
回复
共享的数据你可以单独写一个辅助类,里面写静态的数据:class myHelp 里面关联:static QString str = “ ”,先定义为空,进行赋值后:myHelp::str 即可为两个线程同时使用,数据也不会更改
qt_dog 2016-07-21
  • 打赏
  • 举报
回复
movetothread()函数?

16,175

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧