QT 多线程编程系列1:线程状态演示

51 篇文章 2 订阅
  1. 程序结果:

  1. 创建Widget工程

工程文件截图,

MultiThread001.pro如下,

#-------------------------------------------------
#
# Project created by QtCreator 2023-03-08T16:29:33
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = MultiThread001
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
        executor.cpp \
        main.cpp \
        thread.cpp \
        widget.cpp

HEADERS += \
        executor.h \
        irunable.h \
        thread.h \
        widget.h

FORMS += \
        widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
  1. 添加线程类thread继承自QThread

thread.h

#ifndef THREAD_H
#define 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;
};

#endif // THREAD_H

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)
        {
            qDebug() << "Receive Pause signal! pause the thread";

            mutex.lock();
            condition.wait(&mutex);
            mutex.unlock();
        }
    }
    pauseFlag = false;
    stopFlag = false;

    qDebug() << "exit thread : " << QThread::currentThreadId();
}
  1. 添加执行器类Executor,继承自Thread

executor.h

#ifndef EXECUTOR_H
#define EXECUTOR_H

#include "thread.h"
#include "irunable.h"

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

    void addRunable(IRunable* able);
    void addRunables(const QList<IRunable*>& ables);
    QList<IRunable*> getRunables();

    void setStartupDelay(int ms);
    void setIntervalDelay(int ms);

    void start(Priority pri = InheritPriority);

protected:
    virtual void process() override;

private:
    QList<IRunable*> runableList;
    int startupDelay;
    int intervalDelay;
};

#endif // EXECUTOR_H

executor.cpp

#include "executor.h"
#include <QTimer>
#include <QEventLoop>

Executor::Executor(QObject *parent)
    : Thread(parent),
      startupDelay(0),
      intervalDelay(0)
{

}

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

void Executor::addRunable(IRunable *able)
{
    runableList.append(able);
}

void Executor::addRunables(const QList<IRunable *> &ables)
{
    runableList.append(ables);
}

QList<IRunable *> Executor::getRunables()
{
    return runableList;
}

void Executor::setStartupDelay(int ms)
{
    startupDelay = ms;
}

void Executor::setIntervalDelay(int ms)
{
    intervalDelay = ms;
}

void Executor::start(QThread::Priority pri)
{
    if (startupDelay != 0)
    {
        QTimer::singleShot(startupDelay, this, [=]
        {
            Thread::start(pri);
        });
    }
    else
    {
        Thread::start(pri);
    }
}

void Executor::process()
{
    foreach (auto able, runableList)
    {
        able->exec();
    }

    if (intervalDelay != 0)
    {
        QTimer::singleShot(intervalDelay, this, [=]
        {
            Thread::resume();
        });
        Thread::pause();
    }
}

irunable.h

#ifndef IRUNABLE_H
#define IRUNABLE_H

class IRunable
{
public:
    virtual ~IRunable() {}
    virtual void exec() = 0;
};

#endif // IRUNABLE_H
  1. 主界面程序

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include "executor.h"

namespace Ui {
class Widget;
}

class Executor;
class IRunable;

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButtonStart_clicked();

    void on_pushButtonStop_clicked();

    void on_pushButtonPause_clicked();

    void on_pushButtonResume_clicked();

    void on_pushButtonStatus_clicked();

    void showThreadMessage(QString strMessage);

private:
    Ui::Widget *ui;

    Executor* executor;
    QList<IRunable*> runableList;
};

class Task1 : public QObject,public IRunable
{
    Q_OBJECT

public:
    virtual void exec() override;

signals:
    void showTaskMessage(QString strMessage);
};

class Task2 : public QObject, public IRunable
{
    Q_OBJECT

public:
    virtual void exec() override;

signals:
    void showTaskMessage(QString strMessage);
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QDebug>
#include "Executor.h"
#include "IRunable.h"

#include <windows.h>

void Task1 ::exec()
{
    //qDebug() << "do Task1...";
    emit showTaskMessage("do Task1...");
    Sleep(500);
}


void Task2 ::exec()
{
    //qDebug() << "do Task2...";
    emit showTaskMessage("do Task2...");
    Sleep(500);
}

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    executor = new Executor();
    //executor->setStartupDelay(1000);
    //executor->setIntervalDelay(1000);

    Task1* pTask1 = new Task1();
    Task2* pTask2 = new Task2();

    runableList.append(pTask1);
    runableList.append(pTask2);
    executor->addRunables(runableList);

    connect(pTask1, SIGNAL(showTaskMessage(QString)), this,SLOT(showThreadMessage(QString)));
    connect(pTask2, SIGNAL(showTaskMessage(QString)), this,SLOT(showThreadMessage(QString)));
}

void Widget::showThreadMessage(QString strMessage)
{
    ui->textEdit->append(strMessage);
}

Widget::~Widget()
{
    delete executor;
    executor = nullptr;
    qDeleteAll(runableList);
    runableList.clear();

    delete ui;
}

void Widget::on_pushButtonStart_clicked()
{
    ui->textEdit->append("Thread start");

    executor->start();
}

void Widget::on_pushButtonStop_clicked()
{
    ui->textEdit->append("Thread stop");

    executor->stop();
}

void Widget::on_pushButtonPause_clicked()
{
    ui->textEdit->append("Thread Pause");

    executor->pause();
}

void Widget::on_pushButtonResume_clicked()
{
    ui->textEdit->append("Thread resume");

    executor->resume();
}

void Widget::on_pushButtonStatus_clicked()
{
    ui->textEdit->append("Thread status");

    Thread::State s = executor->state();
    if (s == Thread::Stoped)
    {
        //qDebug() << "state : Stoped";
        showThreadMessage("state : Stoped");
    }
    else if (s == Thread::Running)
    {
        //qDebug() << "state : Running";
        showThreadMessage("state : Running");
    }
    else if (s == Thread::Paused)
    {
        //qDebug() << "state : Paused";
        showThreadMessage("state : Paused");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值