天天看点

Qt多线程的三种方法QtConcurrent::run()+QThreadPool

作者:QT教程

一、简介

QtConcurrent这是一个高级 API,构建于QThreadPool之上,它提供更高层次的函数接口(APIs),使所写的程序,可根据计算机的CPU核数,自动调整运行的线程数量。通常用于处理大多数通用的并行计算模式。

注意,QtConcurrent是一个命名空间而不是一个类,因此其中的所有函数都是命名空间内的全局函数。

二、使用方法

1. 添加concurrent

从Qt4.4之后,QtConcurrent从core模块中独立出来,作为单独的模块。

所以先要在.pro中添加 QT += concurrent

QT += core gui concurrent           

2. 使用方法

可以分别将外部函数,lambda表达式,成员函数运行在某一个线程中。

调用外部函数

调用Lambda表达式(同外部函数)

调用成员函数

调用常量成员函数

代码如下:

//1.调用外部函数func1,并得到返回值
QFuture<QString> f1 =QtConcurrent::run(func1,QString("aa"));
f1.waitForFinished();
qDebug()<<f1.result();
//2.调用Lambda函数,实际同外部函数方式
QThreadPool pool;
QFuture < void > future = QtConcurrent::run([=](){
qDebug() << __FUNCTION__ << QThread::currentThreadId() << QThread::currentThread();
});
QFuture < void > future2 = QtConcurrent::run([=](){
qDebug() << __FUNCTION__ << QThread::currentThreadId() << QThread::currentThread();
});
//3.调用成员函数
QFuture<void> future3 = QtConcurrent::run(this, &Dialog::memberFun1);
//4.常量成员函数QByteArray::split()
QByteArray bytearray = "hello,world";
QFuture<QList<QByteArray>> future4 = QtConcurrent::run(bytearray, &QByteArray::split, ',');
QList<QByteArray> result = future4.result();
qDebug()<<"result:"<<result;           

运行如下:

func1 "aa" 0xacc QThreadPoolThread(0x3d421d0, name = "Thread (pooled)")
"func1 return"
operator() 0xacc QThreadPoolThread(0x3d421d0, name = "Thread (pooled)")
operator() 0x70ac QThreadPoolThread(0x3d42090, name = "Thread (pooled)")
memberFun1 0x8a88 QThreadPoolThread(0x3d421b0, name = "Thread (pooled)")
result: ("hello", "world")           

三、Qt多线程三种方法总结

Qt多线程的三种方法QtConcurrent::run()+QThreadPool

四、不同开发场景下的考虑

需要线程的生命周期 开发场景 解决方案
单次调用 在其他的线程中运行一个方法,当方法运行结束后退出线程。 1)编写一个函数,然后利用 QtConcurrent::run()运行它;(2)从QRunnable 派生一个类,并利用全局线程池QThreadPool::globalInstance()->start()来运行它。(3) 从QThread派生一个类, 重载QThread::run() 方法并使用QThread::start()来运行它。
单次调用 一个耗时的操作必须放到另一个线程中运行。在这期间,状态信息必须发送到GUI线程中。 使用 QThread,,重载run方法并根据情况发送信号。.使用queued信号/槽连接来连接信号与GUI线程的槽。
常驻 有一对象位于另一个线程中,将让其根据不同的请求执行不同的操作。 这意味与工作者线程之间的通信是必须的。 从QObject 派生一个类并实现必要的槽和信号,将对象移到一个具有事件循环的线程中,并通过queued信号/槽连接与对象进行通信。

【领QT开发教程学习资料,点击下方链接莬费领取↓↓,先码住不迷路~】

点击这里:「链接」

继续阅读