针对上一篇 while循环中响应QTimer的方法做了相关优化替代方案qt子线程中存在while死循环时,同时响应QTimer定时器_qt 子线程定时器_blueman8888的博客-CSDN博客
采用信号槽的方式实现,由于执行的当前槽函数与信号处于同一线程中,故信号槽采用人为指定为队列连接方式,让槽的执行进入到子线程的事件队列中。保证不会进入死循环中,如果采用默认连接或者直接连接方式,则会进入类似死循环的递归调用中。
void qcNCCommun::slotCommunToCrtl()
{
//与控制器通讯
//开始读写运动控制卡
m_pCtrl->ReadWriteMotionCtrl();
if (m_bStart)
{
QThread::msleep(10);
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信号槽机制功能非常强大,合理的利用信号槽及其连接方式,在一般的应用领域(绝大部分的领域)都可以取代同步锁,实现良好且逻辑清晰美观的多线程的编程。但是取代不了死循环的实现方式。