《QT从基础到进阶·十九》QThread多线程使用

简介: 《QT从基础到进阶·十九》QThread多线程使用

1、平时在写多线程的时候有时候会遇到下面一种情况:

情景:

this是主线程,model是子线程,把model move到线程后可以在主线程通过emit开启子线程,emit CalcuSignal();开启子线程执行StartCalculateAll,里面有是个循环。emit CancelSignal(true);开启子线程执行CancelSlot(bool),把bool值给到isFinish。

在StartCalculateAll里面循环的时候会判断isFinish值,如果是true就退出循环。

现在这样操作:

先emit CalcuSignal();//子线程执行十遍循环,每遍循环结束都会判断下isFinish

然后通过点击按钮触发emit CancelSignal(true); //我预想结果是一旦执行这条,就会在子线程CancelSlot方法中给isFinish赋true,然后循环会在当前这遍结束判断isFinish为true退出。

结果是:

先emit CalcuSignal();//开启子线程执行循环

循环还没结束emit CancelSignal(true); //无法开启子线程发送信号,直到循环全部结束才开启子线程把信号传递过来。

原因:

因为StartCalculateAll和CancelSlot都是在同一子线程中执行的,StartCalculateAll还没执行完的时候无法执行同一线程其他方法

这样修改:

先emit CalcuSignal();//开启子线程执行循环

循环还没结束在主线程model.CancelSlot(true); //这属于主线程给isFinish赋值,这样两者不在一个线程,循环会在当前结束判断isFinish为ture退出。

2、线程锁:

线程锁需要注意的问题:

(1)线程锁可以设置静态或者全局变量,不管多线程创建几个对象,静态和全局都是一个,所有线程共享

(2)线程锁不能设成成员变量,因为一旦多线程同时创建多个对象时,线程锁就是多个,不是同一份

通常,我们使用的锁为QMutex或Mutex,这里在介绍一种锁:读写锁。

案例会在下面多线程使用方式2说到。

3、多线程使用案例:

多线程使用方式1:moveToThread

自定义一个线程类继承QObject

定义一个控制器去触发线程,在控制器类中声明QThread

注意:

thead.star()后并不会执行线程的内容,仅仅是启动了线程,线程的内容是doWork函数里的内容,当发送信号emit operate后才是真正执行线程的内容doWork函数。

如果myThread mthread定义的是对象不是指针,那connect(… &QObject::deleteLater)就不用写,这条是让子线程能够在主线程析构后进行子线程析构用的(类似于delete 对象),因为不是new出来的,栈区对象可以自己销毁,所以不用写这条。

析构线程的时候需要调用quit(停止事件循环)和wait(阻塞直到线程结束)函数。

多线程使用方式2

继承QThread,重写run方法

自定义两个类readthread和writethread类继承QThread,重写run方法,一个读数据,一个写数据。main方法中启动十个读线程和一个写线程进行读写数据。

读操作是不断从数组中读取数据。

写操作,在数组中随机写入一个随机数,然后休眠一秒。

注意:

重写run函数的多线程继承QThread类不是QObject,结束线程只要thread.wait()就可以了,不用quit,但要设置线程出口。

线程在调用start后开始执行工作。

不同线程共用同一个锁可以防止同时打印数据,比如两个线程同时打印0-100,如果给两个线程不加锁,或者各自定义一个锁,那两个线程都会一起打印0-100,如果两个线程用同一个锁,那么在第一个线程打印0的时候,第二个线程阻塞,当第一个线程释放锁的时候,第一个或第二个线程谁先抢到锁谁继续打印。

3、线程的深度理解和析构问题

直接在方法里面创建子线程对象,start函数会启动子线程的run方法

打印结果如下:

Clicked方法里先创建线程对象所以第一条走构造,t1t.start()结束后clicked()函数也结束,因为线程对象是在栈区创建的,所以clicked()函数结束,线程对象也销毁,所以还没等到执行run函数就先走了析构对线程内容进行强制清理,这时候在走run肯定报错,所以考虑线程对象通过堆区创建:

运行没问题但是需要手动释放内容,修改如下:

线程run方法执行完毕后会触发finished信号,deleteLater函数可以让线程执行完毕后自动释放资源。

📢博客主页: 主页

📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

📢本文由 梦回阑珊 原创,首发于 CSDN,转载注明出处🙉

📢代码改变世界,你来改变代码!✨

相关文章
|
2月前
|
算法 Unix 调度
【Qt 线程】深入探究QThread线程优先级:原理、应用与最佳实践
【Qt 线程】深入探究QThread线程优先级:原理、应用与最佳实践
144 0
|
2月前
|
算法 Unix Linux
Linux与Qt线程优先级的对应关系:一次全面解析
Linux与Qt线程优先级的对应关系:一次全面解析
48 0
|
2月前
|
安全 数据处理 C++
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
454 3
|
2月前
|
存储 安全 Java
Qt线程池+生产者消费者模型
Qt线程池+生产者消费者模型
71 5
|
10天前
|
调度
【浅入浅出】Qt多线程机制解析:提升程序响应性与并发处理能力
在学习QT线程的时候我们首先要知道的是QT的主线程,也叫GUI线程,意如其名,也就是我们程序的最主要的一个线程,主要负责初始化界面并监听事件循环,并根据事件处理做出界面上的反馈。但是当我们只限于在一个主线程上书写逻辑时碰到了需要一直等待的事件该怎么办?它的加载必定会带着主界面的卡顿,这时候我们就要去使用多线程。
|
18天前
|
调度
技术笔记:QT之深入理解QThread
技术笔记:QT之深入理解QThread
14 0
|
1月前
|
Python
在python的应用程序中如何终止QThread 线程
在python的应用程序中如何终止QThread 线程
|
2月前
|
Java API C++
【C++ 与Qt 线程】C++ std::thread 与Qt qthread多线程混合编程
【C++ 与Qt 线程】C++ std::thread 与Qt qthread多线程混合编程
129 1
|
2月前
|
Java 程序员 API
【深入探究 Qt 线程】一文详细解析Qt线程的内部原理与实现策略
【深入探究 Qt 线程】一文详细解析Qt线程的内部原理与实现策略
224 0
|
2月前
|
安全
深入理解Qt多线程编程:QThread、QTimer与QAudioOutput的内在联系__Qt 事件循环(三)
深入理解Qt多线程编程:QThread、QTimer与QAudioOutput的内在联系__Qt 事件循环
85 0