原理说明:
1.QThread是通过isRunning(), isInterruptionRequested(),isFinished(),这3个函数判断线程的状态
*isRunning():初始false,start()之后进入run(),只要是run()没有退出就是true;
*isInterruptionRequested():这个是Qt内部通过锁实现的(安全的), 通过requestInterruption()请求中断和wait()使得线程退出(前提是run()中用了isInterruptionRequested()判断),
这个返回值只有再requestInterruption()后,且wait()之间为true,其他时间都是false;
*isFinished():初始为false,在run()执行完一次之后为true,再次start()后重置为false;
封装ta的原因:
1.业务需要实现线程暂停/恢复
2.记下来,把脑子放空(防止脱发)
//xqthread.h
#ifndef XQTHREAD_H
#define XQTHREAD_H
#include <QThread>
#include <QMutex>
class XQThread : public QThread
{
Q_OBJECT
public:
explicit XQThread(QObject *parent = nullptr);
//虚析构函数(保证子类空间释放)
virtual ~XQThread();
typedef enum X_THREAD_STATUS_
{
XTS_IDLE, //线程空闲
XTS_START, //线程开启
XTS_RUNING, //线程工作
XTS_PAUSE, //线程暂停
}X_THREAD_STATUS_E;
//获取线程状态
X_THREAD_STATUS_E xQThreadStatus();
//线程开始,进入run()
void xQThreadStart(Priority pri = InheritPriority);
//线程停止,安全退出run(在run()处理完当前次的循环后)
void xQThreadStop();
//线程暂停,runMutex加锁(在run()处理完当前次的循环后)
void xQThreadPause();
//线程恢复,runMutex解锁(run()继续执行)
void xQThreadResume();
protected:
//线程工作循环,run()是QThread的虚函数,重写实现业务功能(注意只有run才是跑在线程中的)
virtual void run() override;
QMutex pauseMutex; //Pause锁
X_THREAD_STATUS_E eStatus = XTS_IDLE; //线程状态
};
#endif // XQTHREAD_H
//xqthread.cpp
#include "xqthread.h"
XQThread::XQThread(QObject *parent) : QThread(parent)
{
}
XQThread::~XQThread()
{
//删除对象时要先停止工作线程
xQThreadStop();
}
XQThread::X_THREAD_STATUS_E XQThread::xQThreadStatus()
{
return eStatus;
}
//线程开始,进入run()
void XQThread::xQThreadStart(Priority pri)
{
if(!isRunning() && XTS_IDLE == eStatus)
{
//调用子类start();
QThread::start(pri);
eStatus = XTS_START; //在进入run函数之前,只能认为是start的状态
}
}
//线程停止,退出run(在run()处理完当前次的循环后)
void XQThread::xQThreadStop()
{
if(isRunning() && !isInterruptionRequested())
{
requestInterruption();
if(XTS_PAUSE == eStatus)
{
//暂停状态下stop要解锁(解锁之前先requestInterruption(),保证下次循环判断中断成功)
//不过经过测试,这个先后顺序并不影响,不过这样写个人认为比较严谨(希望大🐮的指正)
pauseMutex.unlock();
}
wait();
}
}
//线程暂停,runMutex加锁(在run()处理完当前次的循环后)
void XQThread::xQThreadPause()
{
if(isRunning())
{
pauseMutex.lock();
eStatus = XTS_PAUSE;
}
}
//线程恢复,runMutex解锁(run()继续执行)
void XQThread::xQThreadResume()
{
if(isRunning() && XTS_PAUSE == eStatus)
{
pauseMutex.unlock();
eStatus = XTS_RUNING;
}
}
//线程工作循环,run()是QThread的虚函数,重写实现业务功能(注意只有run才是跑在线程中的)
void XQThread::run()
{
eStatus = XTS_RUNING; //线程进入,修改状态为runing
while(!isInterruptionRequested())
{
QMutexLocker lock(&pauseMutex); //这个锁的作用是控制 暂停/恢复
//TODO : want to execute
msleep(1);
}
eStatus = XTS_IDLE; //线程退出,修改状态为idle
}
如有不足,欢迎指正!