QThread中当前的子线程出现了msleep,配合invokeMethod出现死锁问题
先看当前代码
点击查看代码
class SafetyWork:public QObject
{
Q_OBJECT
public:
explicit SafetyWork(MotionCardInterface*card,QObject *parent = nullptr);
public slots:
void startMotion(int intervalMs=100);//开始检查
void stopMotion();//停止检查
void Checking();//具体的检查
signals:
void SafetyError(int code,const QString&errorMessage);//安全检查出现问题
void safetyStatusChanged(bool isSafe);//安全状态改变
private:
MotionCardInterface*m_card=nullptr;//控制卡
bool m_running=false;//是否在运行
//std::atomic<bool> m_running{false};
};
class SafetyMonitor : public QObject
{
Q_OBJECT
public:
explicit SafetyMonitor(MotionCardInterface*card,QObject *parent = nullptr);
~SafetyMonitor();
void start(int intervalMs=100);//开始监控检查
void stop();//结束监控检查
signals:
void SafetyError(int code,const QString&errorMessage);//安全检查出现问题
void safetyStatusChanged(bool isSafe);//安全状态改变
private:
QThread*m_thread;
SafetyWork*m_safetyWork;
};
//启动检查
void SafetyWork::startMotion(int intervalMs)
{
this->m_running=true;
while(this->m_running)
{
this->Checking();
QThread::msleep(intervalMs);
}
}
//停止检查
void SafetyWork::stopMotion()
{
this->m_running=false;
}
void SafetyWork::Checking()
{
if(!this->m_card)return;
bool estop = false;//急停释放
bool doorClosed = false;//安全门是否正常关闭
bool airPressure = false;//气压是否正常
this->m_card->readInput(0,estop);
this->m_card->readInput(1,doorClosed);
this->m_card->readInput(2,airPressure);
if(!estop)
{
emit SafetyError(0,"急停未释放");
emit safetyStatusChanged(false);
return;
}
if(!doorClosed)
{
emit SafetyError(1,"安全门未关闭");
emit safetyStatusChanged(false);
return;
}
if(!airPressure)
{
emit SafetyError(2,"气压出现问题");
emit safetyStatusChanged(false);
return;
}
emit safetyStatusChanged(true);
}
SafetyMonitor::SafetyMonitor(MotionCardInterface *card, QObject *parent)
{
this->m_thread=new QThread(this);
this->m_safetyWork=new SafetyWork(card);
this->m_safetyWork->moveToThread(this->m_thread);
connect(this->m_safetyWork,&SafetyWork::SafetyError,this,&SafetyMonitor::SafetyError);
connect(this->m_safetyWork,&SafetyWork::safetyStatusChanged,this,&SafetyMonitor::safetyStatusChanged);
}
SafetyMonitor::~SafetyMonitor()
{
this->stop();
}
//启动监控检查
void SafetyMonitor::start(int intervalMs)
{
if(this->m_thread->isRunning())return;
this->m_thread->start();
//只需要单次调度即可,否则用connect也可
QMetaObject::invokeMethod(this->m_safetyWork, "startMotion",
Qt::QueuedConnection,
Q_ARG(int, intervalMs));
//connect(this->m_thread,&QThread::started,this->m_safetyWork,&SafetyWork::startMotion,Qt::QueuedConnection);
}
//结束监控检查
void SafetyMonitor::stop()
{
if(this->m_thread->isRunning())
{
QMetaObject::invokeMethod(this->m_safetyWork,
"stopMotion", Qt::BlockingQueuedConnection);
this->m_thread->quit();
this->m_thread->wait();
if (m_safetyWork) {
delete m_safetyWork;
m_safetyWork = nullptr;
}
}
}
点击查看代码
std::atomic<bool> m_running{false};
void SafetyWork::startMotion(int intervalMs)
{
this->m_running=true;
while(this->m_running.load())
{
this->Checking();
QThread::msleep(intervalMs);
}
}
浙公网安备 33010602011771号