Qt多线程

示例

moveToThread示例

要点

  • 使用moveToThread()创建子线程;
  • 使用QMutex/QWaitCondition进行线程同步(适用情况:子线程主动挂起,等待主线程唤醒)。

代码

worker.h
#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include <QMutex>
#include <QWaitCondition>

class Worker : public QObject
{
    Q_OBJECT

public:
    explicit Worker(QObject* parent = nullptr);

public:
    void DoWorker();
    void RecoverWork();

signals:
    void SignalRecover();
    void SignalStart();

private slots:
    void OnRecovered();
    void OnStarted();

private:
    QMutex m_mutex;
    QWaitCondition m_waitCondition;
};

#endif // WORKER_H
worker.cpp
#include "worker.h"
#include <QDebug>
#include <QThread>

Worker::Worker(QObject *parent)
    : QObject{parent}
{
    connect(this, &Worker::SignalStart, this, &Worker::OnStarted);
    connect(this, &Worker::SignalRecover, this, &Worker::OnRecovered);
}

void Worker::DoWorker()
{
    qDebug() << QThread::currentThreadId() << "in DoWorker";
    emit SignalStart();
}

void Worker::RecoverWork()
{
    qDebug() << QThread::currentThreadId() << "in RecoverWork";
    qDebug() << QThread::currentThreadId() << "m_waitCondition.wakeAll";
    m_waitCondition.wakeAll();
}

void Worker::OnRecovered()
{
    qDebug() << QThread::currentThreadId() << "in OnRecovered";
}

void Worker::OnStarted()
{
    qDebug() << QThread::currentThreadId() << "in OnStarted";
    int i = 0;
    while (true)
    {
        m_mutex.lock();
        qDebug() << QThread::currentThreadId() << "in OnStarted sleep" << i;
        QThread::sleep(1);
        ++i;

        if (i % 5 == 0)
        {
            qDebug() << QThread::currentThreadId() << "m_waitCondition.wait" << i;
            m_waitCondition.wait(&m_mutex);
        }
        m_mutex.unlock();
    }
}
contrllor.h
#ifndef CONTRLLOR_H
#define CONTRLLOR_H

#include <QObject>

class Worker;

class Contrllor : public QObject
{
    Q_OBJECT

public:
    explicit Contrllor(QObject* parent = nullptr);
    ~Contrllor();

public:
    Q_INVOKABLE void doWork();
    Q_INVOKABLE void pauseWork();
    Q_INVOKABLE void recoverWork();

    Q_INVOKABLE void test();

signals:

private:
    QThread* m_workerThread;
    Worker* m_worker;
};

#endif // CONTRLLOR_H
contrllor.cpp
#include "contrllor.h"

#include <QDebug>
#include <QThread>

#include "worker.h"

Contrllor::Contrllor(QObject *parent)
    : QObject{parent}
{
    qDebug() << "in Contrllor";
    m_workerThread = new QThread;
    m_worker = new Worker;
    m_worker->moveToThread(m_workerThread);
    m_workerThread->start();
}

Contrllor::~Contrllor()
{
    qDebug() << QThread::currentThreadId() << "in ~Contrllor";
    m_workerThread->terminate();
    if (m_workerThread->wait())
    {
        delete m_worker;
        delete m_workerThread;
    }
    qDebug() << QThread::currentThreadId() << "out ~Contrllor";
}

void Contrllor::doWork()
{
    qDebug() << QThread::currentThreadId() << "in doWork";
    m_worker->DoWorker();
}

void Contrllor::pauseWork()
{
    qDebug() << QThread::currentThreadId() << "in pauseWork";
    // TODO-gy-2023-10-15
}

void Contrllor::recoverWork()
{
    qDebug() << QThread::currentThreadId() << "in recoverWork";
    m_worker->RecoverWork();
}

void Contrllor::test()
{
    qDebug() << QThread::currentThreadId() << "in test";
}

关于QWaitCondition

wakeOne与wakeAll的区别

wakeAll

        唤醒所有处于等待状态的线程。线程被唤醒的顺序取决于操作系统的调度策略,无法控制或预测。

wakeOne

        在等待条件下唤醒一个线程。被唤醒的线程取决于操作系统的调度策略,无法控制或预测。
        注意:如果想唤醒一个特定的线程,通常是使用不同的等待条件,并让不同的线程在不同的条件下等待。

引用

QThread Class | Qt Core 5.15.15

QThreadPool Class | Qt Core 5.15.15

Synchronizing Threads | Qt 5.15

QWaitCondition Class | Qt Core 5.15.15

Wait Conditions Example | Qt Core 5.15.15

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值