QT针对子线程中存在while死循环实现的替代方案(错误案例)

针对上一篇 while循环中响应QTimer的方法做了相关优化替代方案qt子线程中存在while死循环时,同时响应QTimer定时器_qt 子线程定时器_blueman8888的博客-CSDN博客

 采用信号槽的方式实现,由于执行的当前槽函数与信号处于同一线程中,故信号槽采用人为指定为队列连接方式,让槽的执行进入到子线程的事件队列中。保证不会进入死循环中,如果采用默认连接或者直接连接方式,则会进入类似死循环的递归调用中。

void qcNCCommun::slotCommunToCrtl()
{
	//与控制器通讯

	//开始读写运动控制卡
	m_pCtrl->ReadWriteMotionCtrl();

	if (m_bStart)
	{
		QThread::msleep(10);
		emit signalRepeatCommunToCrtl();
	}
}

过程描述 :

  1. 在当前程序读写完成后,
  2. 判断是否进行再次读写标识m_bStart,
  3. 为true则QThread::msleep(10)停留10ms,也可以不加,但是CPU会占用很大,所以还是添加一个降低当前发送信号频率的延时。
  4. 发送再次读取的信号emit signalRepeatCommunToCrtl()

信号槽采用队列方式

connect(this, &qcNCCommun::signalRepeatCommunToCrtl, 
		this, &qcNCCommun::slotCommunToCrtl,Qt::QueuedConnection);

上述方案缺点:

当信号无限循环发送时,对应槽函数也将无限的在事件循环中执行,当槽函数执行次数太多后,将影响后续其他的槽函数,并且进入一个恶性循环中,随着运行时间越长,其他槽函数将越久时间响应。大缺点。 

原方案:

void qcNCCommun::slotCommunToCrtl()
{
	//与控制器通讯
	while (m_bStart)
	{
		//开始读写运动控制卡
		m_pCtrl->ReadWriteMotionCtrl();
		QCoreApplication::processEvents();
		QThread::msleep(10);
	}

}

原方案优点 :

不会频繁的往线程事件循环中发送信号,只在程序执行过程中发送一个交还事件的消息。不存在阻塞问题。 

总结:qt信号槽机制功能非常强大,合理的利用信号槽及其连接方式,在一般的应用领域(绝大部分的领域)都可以取代同步锁,实现良好且逻辑清晰美观的多线程的编程。但是取代不了死循环的实现方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值