qt 多线程

Posted 马肯尼煤牙巴骨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qt 多线程相关的知识,希望对你有一定的参考价值。

比较旧的方法是 通过继承,重写run方法
设置线程优先级, start() ,后会调 run run结束后,thead会结束执行,但需要手动销毁。 其他有用的方法 wait(), quit(), exit() deletelater(); exec() ;
如果没有exec(), 则不能接收信号槽 ,exec()是默认的run实现执行的, 如果重写了run, 也要写一下exec()

也可以使用qthread::create,传入方法,参数, 去运行

也可以通用信号槽,把对像Move到线程上, 使用线程默认的exec(),来执行对像的方法,这种方式也不需要继承,重载
通常会用到这几个信号
started -> 执行对象成员方法
对象方法结束信号 -> quit
finished -> 删除对象
当然这种方式不是很面向对象,所以更进一步,封闭对象,把qthread对使用者藏匿起来也是可以的

qthread只有run方法是在其他线程的, 它本身属于构建他的线程

在异步线程中, 不可以调用主线程的控件, widget, qml ,或pixelmap 相关的api
但是可以处理qimage painter , opengl, 处理opengl时,需要检测一下,是否支持多线程 qopenglcontext:;supportstheadedopengl()

多线程中为了防止数据竞争,需要用到锁
qmutux 递归 性能不好 非递归 非递归性能好点,但要确保不要在同一个线程多次访问同一个上锁的方法
qsemaphore 信号量,
qwaitcondition
qreadwritelock 支持同时读,但不支持写的时候在读或在写
qatomicint 安全并发的加整数
qatomicPointer 安全并发的加指针
qspinlock 自旋

raii用的类
qmutexlocker,qreadloader 等

qthread中也有 requestInterruption, 和isInterruptionRequested ,用来做一个多纯正程安全的退出请求,类似c#中的task cancel token


概念
线程安全方法, 多线程同一时间,在同一数据上执行, 不需要同步

可重入方法:多线程同一时间,不同数据上执行, 否则需要额外同步

不可重入方法: 又称非线程安全 ,不可以在不同线程访问

对于类,上面的说法适用于非静态成员函数 (把this当成参数来看待

Qt多线程:QtConcurrent + QFuture + QFutureWatcher

参考技术A

QtConcurrent 实际是一个命名空间,该命名空间提供了高级API,从而可以在不使用低级线程原语(启动线程、线程间同步、锁等)的情况下编写多线程程序。

但是QtConcurrent仅支持接受纯函数或者lambda表达式,不支持信号和槽,如果需要监听任务执行结果可以通过与QFuture和QFutureWatcher配合来达到。

QFuture 类表示异步计算的结果,使用Qt Concurrent框架中的API启用。

要使用信号和插槽与正在运行的任务进行交互,则需要使用QFutureWatcher。

QFutureWatcher 类允许使用信号和插槽监视QFuture。

简单的例子:

通过运行结果可以发现,QtConccurent管理的线程实际是从线程池分配线程资源的,而绑定QFutureWatcher的槽是在主线程中执行的。
在需要单次执行且内部逻辑较简单的时候使用QtConccurrent+QFuture+QFutureWatcher是很方便的,可以减少很多编码工作量,而且在多cpu环境中,QtConccurent也会启用多核。

以上是关于qt 多线程的主要内容,如果未能解决你的问题,请参考以下文章

QT开发(三十四)——QT多线程编程

QT中的信号与事件,多线程

QT多线程问题:子线程中的变量如何传递给主线程?

Qt入门教程QObject篇多线程方案分析

Qt多线程(有详细例子)

Qt多线程——方式2