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

你可能感兴趣的:(QT,qt,开发语言)