【Qt】多线程

Qt中多线程相关的类

QThreadQThread类是Qt中用于创建和管理线程的基类。通过继承QThread类并重写其中run()函数,可以定义自己的线程类。
QMutexQMutex类是Qt中用于实现线程间互斥访问的类。它可以用于保护共享资源,避免多个线程同时访问导致的竞争问题。
QMutexLockerQMutexLocker类是Qt中用于自动管理互斥锁的类。它可以在作用域结束时自动释放互斥锁,避免忘记手动释放锁导致的问题。
QWaitConditionQWaitCondition类是Qt中用于线程间等待和唤醒的类。它可以用于实现线程间的同步和通信。
QThreadPoolQThreadPool类是Qt中用于管理线程池的类。线程池可以用于管理多个线程的执行,提高线程的复用性和效率。
QRunnableQRunnable类是Qt中用于表示可执行任务的类。通过继承QRunnable类并实现其中run()函数,可以定义自己的可执行任务。

QThread使用

        QThread有两种使用方式:

继承QThread 重写 run()方法QThread是Qt提供的一个线程类,可以用于创建和管理线程。它是QObject的子类,提供了一些方便的方法来控制线程的执行。通过继承QThread类并重写run()方法,可以在一个独立的线程中执行自定义代码。使用QThread可以实现线程的创建、启动、中断、等待等操作。
QObject::moveToThread()QObject::moveToThread()是QObject类的成员函数,用于将一个QObject对象移动到另一个线程中执行。当一个QObject对象被移动到一个新的线程时,它的事件循环会在新线程中启动,从而使得该对象的信号和槽以及其他事件能够在新线程中得到处理。

继承QThread重写run()函数方式

#include <QThread>
#include <QDebug>

// 自定义的工作线程类
class WorkerThread : public QThread{
    Q_OBJECT
public:
    void run() override{
        qDebug() << "Worker thread ID: " << QThread::currentThreadId();
        // 执行一些耗时的操作
        for (int i = 0; i < 5; ++i){
            qDebug() << "Working... " << i;
            sleep(1);
        }
    }
};
int main(int argc, char *argv[]){
    QCoreApplication app(argc, argv);
    qDebug() << "Main thread ID: " << QThread::currentThreadId();
    WorkerThread workerThread;// 创建工作线程
    workerThread.start();// 启动工作线程
    workerThread.wait();// 等待工作线程完成
    qDebug() << "Worker thread finished.";// 输出工作线程结束后的提示信息
    return app.exec();
}

        可以在自定义的工作线程类的构造函数中添加:

 connect(this,&QThread::finished,[this](){deletelater();});

         该行代码是在线程结束后,自动销毁此线程。

QObject::moveToThread()方式

#include <QThread>
#include <QObject>
#include <QDebug>

// 自定义的工作类
class Worker : public QObject{
    Q_OBJECT
public slots:
    // 执行工作任务
    void doWork(){
        qDebug() << "Worker thread ID: " << QThread::currentThreadId();
        for (int i = 0; i < 5; ++i){
            qDebug() << "Working... " << i;
            QThread::sleep(1);
        }
        emit workFinished();// 发送工作完成信号
    }
signals:
    void workFinished();
};

int main(int argc, char *argv[]){
    QCoreApplication app(argc, argv);
    qDebug() << "Main thread ID: " << QThread::currentThreadId();
    Worker worker;// 创建工作对象 
    QThread workerThread;// 创建工作线程 
    worker.moveToThread(&workerThread);// 将工作对象移动到工作线程中
    QObject::connect(&worker, &Worker::workFinished, &app, &QCoreApplication::quit);// 连接工作完成信号
    workerThread.start();// 启动工作线程
    QMetaObject::invokeMethod(&worker, "doWork", Qt::QueuedConnection);// 在工作线程中执行工作
    return app.exec();// 运行主线程事件循环
}

QMutex

#include <QCoreApplication>
#include <QMutex>
#include <QThread>
#include <QDebug>

QMutex mutex; // 创建一个互斥锁对象

class Worker : public QObject
{
    Q_OBJECT

public slots:
    void doWork(){
        mutex.lock(); // 锁定互斥锁       
        qDebug() << "Worker thread ID: " << QThread::currentThreadId();
        for (int i = 0; i < 5; ++i){
            qDebug() << "Working... " << i;
            QThread::sleep(1);
        }
        mutex.unlock(); // 解锁互斥锁
    }
};

int main(int argc, char *argv[]){
    QCoreApplication app(argc, argv);
    qDebug() << "Main thread ID: " << QThread::currentThreadId();
    Worker worker;
    QThread workerThread;
    worker.moveToThread(&workerThread);
    QObject::connect(&workerThread, &QThread::started, &worker, &Worker::doWork);
    QObject::connect(&worker, &Worker::finished, &app, &QCoreApplication::quit);
    workerThread.start();
    return app.exec();
}

QMutexLocker

#include <QCoreApplication>
#include <QMutex>
#include <QThread>
#include <QDebug>

QMutex mutex; // 创建一个互斥锁对象

class Worker : public QObject{
    Q_OBJECT
public slots:
    void doWork(){
        QMutexLocker locker(&mutex); // 创建一个QMutexLocker对象,在构造函数中锁定互斥锁 
        qDebug() << "Worker thread ID: " << QThread::currentThreadId();
        for (int i = 0; i < 5; ++i){
            qDebug() << "Working... " << i;
            QThread::sleep(1);
        }
        // QMutexLocker对象的析构函数会自动解锁互斥锁,无需手动调用mutex.unlock()
    }
};

int main(int argc, char *argv[]){
    QCoreApplication app(argc, argv);
    qDebug() << "Main thread ID: " << QThread::currentThreadId();
    Worker worker;
    QThread workerThread;
    worker.moveToThread(&workerThread);
    QObject::connect(&workerThread, &QThread::started, &worker, &Worker::doWork);
    QObject::connect(&worker, &Worker::finished, &app, &QCoreApplication::quit);
    workerThread.start();
    return app.exec();
}

QWaitCondition

#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QDebug>

// 全局互斥量和条件变量
QMutex mutex;
QWaitCondition condition;

// 消费者线程类
class ConsumerThread : public QThread{
public:
    void run(){
        QMutexLocker locker(&mutex);
        qDebug() << "Consumer: Waiting for data...";

        // 当没有数据时等待条件变量被唤醒
        condition.wait(&mutex);

        qDebug() << "Consumer: Data received!";
    }
};

// 生产者线程类
class ProducerThread : public QThread{
public:
    void run(){
        QThread::sleep(2);  // 模拟生产数据的耗时操作

        QMutexLocker locker(&mutex);
        qDebug() << "Producer: Sending data...";

        // 发送信号给消费者线程,唤醒它继续执行
        condition.wakeOne();

        qDebug() << "Producer: Data sent!";
    }
};

int main(){
    ConsumerThread consumerThread;
    ProducerThread producerThread;

    // 启动消费者线程
    consumerThread.start();

    // 启动生产者线程
    producerThread.start();

    // 等待线程结束
    consumerThread.wait();
    producerThread.wait();

    return 0;
}

QRunnable和QThreadPool

#include <QCoreApplication>
#include <QRunnable>
#include <QDebug>
#include <QThreadPool>

// 自定义任务类
class MyTask : public QRunnable{
public:
    void run(){
        qDebug() << "Task started in thread" << QThread::currentThread();

        // 模拟耗时操作
        for (int i = 0; i < 100000000; ++i) {
            // do something
        }

        qDebug() << "Task finished in thread" << QThread::currentThread();
    }
};

int main(int argc, char *argv[]){
    QCoreApplication a(argc, argv);

    // 创建线程池
    QThreadPool threadPool;

    // 设置最大线程数
    threadPool.setMaxThreadCount(4);

    // 创建并提交任务
    for (int i = 0; i < 10; ++i) {
        MyTask *task = new MyTask();
        threadPool.start(task);
    }

    // 等待所有任务完成
    threadPool.waitForDone();

    return a.exec();
}

注意:QRunnable和QThread很相像,都有一个run函数,在run函数为在线程内执行的代码。但是不同的是,QRunnable本身并不创建一个新线程,它需要与QThreadPool线程池一起使用。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值