继承QThread,封装线程开始/停止/暂停/恢复及状态获取

原理说明:
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
}

如有不足,欢迎指正!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值