大家好,又见面了,我是你们的朋友全栈君。
一、实现思路
QThread中有start、quit,但是没有pause,那么我们想要实现这个功能。
- 我们继承QThread,重写run();
- 第一反应是不是应该添加个标志,在run()中判断暂停状态。嗯,没错,不过我们不能用普通变量,否则有线程非安全风险。这里使用C 提供的原子类型std::atomic_bool。
- 线程暂停期间,不能空跑消耗cpu,故我们使用Qt条件变量QWaitCondition,配合QMutex。
大概就是这么点内容吧,实现代码如下:
Thread.h
代码语言:javascript复制#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
代码语言:javascript复制#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%
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/140496.html原文链接:https://javaforall.cn