QThread如何优雅实现暂停(挂起)功能

QThread如何优雅实现暂停(挂起)功能一、实现思路QThread中有start、quit,但是没有pause,那么我们想要实现这个功能。我们继承QThread,重写run();第一反应是不是应该添加个标志,在run()中判断暂停状态。嗯,没错,不过我们不能用普通变量,否则有线程非安全风险。这里使用C++提供的原子类型std::atomic_bool。线程暂停期间,不能空跑消耗cpu,故我们使用Qt条件变量QWaitCondition,配合QMutex。大概就是这么点内容吧,实现代码如下:Thread.h#include&lt

大家好,又见面了,我是你们的朋友全栈君。

一、实现思路

QThread中有start、quit,但是没有pause,那么我们想要实现这个功能。

  • 我们继承QThread,重写run();
  • 第一反应是不是应该添加个标志,在run()中判断暂停状态。嗯,没错,不过我们不能用普通变量,否则有线程非安全风险。这里使用C++提供的原子类型std::atomic_bool。
  • 线程暂停期间,不能空跑消耗cpu,故我们使用Qt条件变量QWaitCondition,配合QMutex。

大概就是这么点内容吧,实现代码如下:

Thread.h

#include <QThread>
#include <atomic>
#include <QMutex>
#include <QWaitCondition>

class Thread : public QThread
{ 
   
    Q_OBJECT
public:
    Thread(QObject *parent = nullptr);
    ~Thread() override;

    enum State
    { 
   
        Stoped,     ///<停止状态,包括从未启动过和启动后被停止
        Running,    ///<运行状态
        Paused      ///<暂停状态
    };

    State state() const;

public slots:
    void start(Priority pri = InheritPriority);
    void stop();
    void pause();
    void resume();

protected:
    virtual void run() override final;
    virtual void process() = 0;

private:
    std::atomic_bool pauseFlag;
    std::atomic_bool stopFlag;
    QMutex mutex;
    QWaitCondition condition;
};

Thread.cpp

#include "Thread.h"
#include <QDebug>

Thread::Thread(QObject *parent)
    : QThread(parent),
      pauseFlag(false),
      stopFlag(false)
{ 
   

}

Thread::~Thread()
{ 
   
    stop();
}

Thread::State Thread::state() const
{ 
   
    State s = Stoped;
    if (!QThread::isRunning())
    { 
   
        s = Stoped;
    }
    else if (QThread::isRunning() && pauseFlag)
    { 
   
        s = Paused;
    }
    else if (QThread::isRunning() && (!pauseFlag))
    { 
   
        s = Running;
    }
    return s;
}

void Thread::start(Priority pri)
{ 
   
    QThread::start(pri);
}

void Thread::stop()
{ 
   
    if (QThread::isRunning())
    { 
   
        stopFlag = true;
        condition.wakeAll();
        QThread::quit();
        QThread::wait();
    }
}

void Thread::pause()
{ 
   
    if (QThread::isRunning())
    { 
   
        pauseFlag = true;
    }
}

void Thread::resume()
{ 
   
    if (QThread::isRunning())
    { 
   
        pauseFlag = false;
        condition.wakeAll();
    }
}

void Thread::run()
{ 
   
    qDebug() << "enter thread : " << QThread::currentThreadId();

    while (!stopFlag)
    { 
   
        process();
        if (pauseFlag)
        { 
   
            mutex.lock();
            condition.wait(&mutex);
            mutex.unlock();
        }
    }
    pauseFlag = false;
    stopFlag = false;

    qDebug() << "exit thread : " << QThread::currentThreadId();
}
  • 支持获取线程状态;
  • start()、stop()、pause()、resume()支持信号槽方式调用;
  • start()、stop()、pause()、resume()支持多次无效调用,对线程运行状态无影响。
  • 禁止子类重写run()方法,而代替为重写process()。

二、惯例

测试,运行效果:
在这里插入图片描述

可以看到暂停时,PauseQThread.exe的CPU使用率为0%


若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

本文涉及工程代码,公众号回复:37PauseQThread,即可下载。

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/140496.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 软件测试必问必背面试题

    软件测试必问必背面试题软件测试必问必背面试题01软件测试理论部分1.1测试概念1.请你分别介绍一下单元测试、集成测试、系统测试、验收测试、回归测试单元测试:完成最小的软件设计单元(模块)的验证工作,目标是确保模块被正确的编码集成测试:通过测试发现与模块接口有关的问题系统测试:是基于系统整体需求说明书的黑盒类测试,应覆盖系统所有联合的部件回归测试:回归测试是指在发生修改之后重新测试先前的测试用例以保证修改的正确性验收测试:这时相关的用户或独立测试人员根据测试计划和结果对系统进行测试和接收。验收测试包括Al

    2022年6月24日
    23
  • 实时数据库与时序数据库区别_时间序列数据库

    实时数据库与时序数据库区别_时间序列数据库1、概述在工业大数据数据库存储领域,除了传统的关系型数据库和分布式数据库以外,还有一种类型的数据库是非常常用,而且是非常有必要的,就是实时数据库,以及时序数据库。但是,大家可能会有疑问,都是专门处理时序数据的,这是两种数据库吗?他们之间有什么联系?1.1发展历史实时数据库是数据库系统的一个分支,它适用于处理不断更新的快速变化的数据及具有时间限制的事务处理。实时数据库技术是实时系统和数据库技术相结合的产物。实时数据库最起初是基于先进控制和优化控制而出现的,对数据的实时性要求比较高,因而实时、高效

    2022年10月5日
    2
  • mysql数据库备份和还原的命令_Mysql数据库备份和还原常用的命令

    mysql数据库备份和还原的命令_Mysql数据库备份和还原常用的命令Mysql数据库备份和还原常用的命令是进行Mysql数据库备份和还原的关键,没有命令,什么都无从做起,更谈不上什么备份还原,只有给系统这个命令,让它去执行,才能完成Mysql数据库备份和还原的操作,下面就是操作的常用命令。一、备份命令1、备份MySQL数据库的命令mysqldump-hhostname-uusername-ppassworddatabasename>backupf…

    2022年5月4日
    56
  • 云服务器搭建_免费云服务器

    云服务器搭建_免费云服务器在前一篇的基础上,现在对服务器进行环境搭建,其实就是安装你需要的软件,配置环境变量,然后安装tomcat。环境搭建1、gitbash连接服务器(或者XShell等工具)2、搭建mysql环境

    2022年8月3日
    10
  • 交易真的能稳定盈利吗_如何在股市稳定盈利

    交易真的能稳定盈利吗_如何在股市稳定盈利作为一个已经稳定盈利的人,我来解答下吧。我主要做外汇,期货和期权,A股也做,但是中国的股票你们知道的,做空的限制太多,融券融不到,股指期货还限制开仓和提高杠杆率。所以要等一个轮回需要5年以上,所以股票等待建仓机会比较漫长。从交易者的层面来看,我一般把他们分为这么几类人:一,幼儿园阶段:无知者无畏这种人没做过交易,只是从朋友那里听说,交易能赚大钱,或者是书刊杂志上读了一些交易大师的成功学传记,然后就跟打了鸡血似的,觉得自己也能和他们一样在金融市场赚到很多钱,这些人没有风控意识,甚至感觉这个市场

    2022年10月4日
    2
  • 和第三方接口对接总结

    和第三方接口对接总结接口对接分为两种形式:我方A公司提供接口给B公司,B公司进行一些操作时调用我们的接口进行实现。例:A开发会员等级同步接口,供B同步会员等级到B系统。B会员等级的变动需要调用A接口主动推送给A(即更新会员卡等级)。我们首先要做的就是按照对方的要求,在对方调用我们的接口,我方成功处理之后,按照对方所需要的返回数据以及格式反馈给他们信息。在写本接口中,因为我们会员卡等级的字段是不一样的,所…

    2022年5月2日
    52

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号