【linux开发-Qt】-Qt多线程开发

QThread 线程类是实现多线程的核心类。Qt 有两种多线程的方法,其中一种是继承 QThread
的 run()函数,另外一种是把一个继承于 QObject 的类转移到一个 Thread 里。

另外 Qt 提供了 QMutex、QMutexLocker、QReadLocker 和 QWriteLocker 等类用于线程之

间的同步,详细可以看 Qt 的帮助文档。

1、继承QThread的线程

主要使用run()方法,是继承于 QThread 类的方法,用户需要重写这个方法,一般是

把耗时的操作写在这个 run()方法里面。

例:

mainwindow.h文件代码如下:

cpp 复制代码
/*新建一个类继承QThread*/
class WThread : public QThread
{
    /* 用到信号槽即需要此宏定义 */
    Q_OBJECT
public:
    WThread(QWidget *parent = nullptr) {
        Q_UNUSED(parent);
    }

    /* 重写 run 方法,继承 QThread 的类,只有 run 方法是在新的线程里 */
    void run() override {
         QString result = "线程开启成功";
    /* 这里写上比较耗时的操作 */
     // ...
     // 延时 2s,把延时 2s 当作耗时操作
     sleep(2);

     /* 发送结果准备好的信号 */
     emit resultReady(result);
     }
}

在mainwindow.cpp中:

cpp 复制代码
#include "mainwindow.h"

/*设置文本*/
....
MainWindow::~MainWindow()
{
    /* 进程退出,注意本例 run()方法没写循环,此方法需要有循环才生效 */
    workerThread->quit();
    
    /* 阻塞等待 2000ms 检查一次进程是否已经退出 */
    if (workerThread->wait(2000)) {
        qDebug()<<"线程已经结束!"<<endl;
    }
}
void MainWindow::handleResults(const QString &result)
 {
     /* 打印出线程发送过来的结果 */
     qDebug()<<result<<endl;
 }

 void MainWindow::pushButtonClicked()
 {
     /* 检查线程是否在运行,如果没有则开始运行 */
     if (!workerThread->isRunning())
     workerThread->start();
 }

2、继承QObiect的线程

继承 QObject 类更加灵活。它通过 QObject::moveToThread()方法,将一个 QObeject的类转移到一个线程里执行。

cpp 复制代码
class Worker : public QObject
public slots:
     /* 耗时的工作都放在槽函数下,工人可以有多份不同的工作,但是每次只能去做一份 */
     void doWork1(const QString &parameter) {

     /* 标志位为真 */
     isCanRun = true;

     /* 死循环 */
     while (1) {
     /* 此{}作用是 QMutexLocker 与 lock 的作用范围,获取锁后,
     /* 运行完成后即解锁 */
     {
         QMutexLocker locker(&lock);
         /* 如果标志位不为真 */
         if (!isCanRun) {
             /* 跳出循环 */
         break;
     }
 }
 /* 使用 QThread 里的延时函数,当作一个普通延时 */
 QThread::sleep(2);

     emit resultReady(parameter + "doWork1 函数");
 }
     /* doWork1 运行完成,发送信号 */
     emit resultReady("打断 doWork1 函数");
 }

 // void doWork2();...

 public:
     /* 打断线程(注意此方法不能放在槽函数下) */
     void stopWork() {
     qDebug()<<"打断线程"<<endl;

     /* 获取锁后,运行完成后即解锁 */
     QMutexLocker locker(&lock);
     isCanRun = false;
 }

 signals:
     /* 工人工作函数状态的信号 */
    void resultReady(const QString &result);
 };

不同于继承 QThread 类的线程 run(),继承 QThread 的类只有 run()在新线程里。而继承 QObject 的类,使用 moveToThread()可以把整个继承的 QObject 类移至线程里执行,所以可以有doWork1(),doWork2...等等耗时的操作,但是这些耗时的操作都应该作为槽函数,由主线程去调用。

mianwindow.cpp参考上面。

学习资料来源:正点原子视频

相关推荐
程序喵大人6 分钟前
【C++进阶】STL容器与迭代器 - 05 map 和 set 为什么按键保持有序
开发语言·c++·容器·迭代器·stl
完美火龙篇 四月的友17 分钟前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
开发语言·php
冻柠檬飞冰走茶39 分钟前
PTA基础编程题目集 7-15 计算圆周率(C语言实现)
c语言·开发语言·数据结构·算法
前端炒粉1 小时前
简易实现ssr
开发语言·前端·javascript
库克克1 小时前
【C++】 unordered_map 与unordered_set
开发语言·c++
风曦Kisaki2 小时前
Kubernetes(K8s)笔记Day03: Pod命名空间,标签,Pod 的调度,污点与容忍度,Pod 常见状态和重启策略,Pod 生命周期
linux·运维·笔记·docker·云原生·容器·kubernetes
雪的季节2 小时前
人工智能 AI 5问
开发语言
xuhe22 小时前
一劳永逸!解决 AutoDL 系统盘(30GB)爆满与 pip 缓存迁移
linux·python·ai·jupyter
李迟2 小时前
一种轻量级C++ CSV文件读写库的实现方案
开发语言·c++
小园子的小菜2 小时前
Java 并发编程:线程安全队列全解 —— 阻塞与非阻塞实现原理及源码深度剖析
java·开发语言