一 什么是QtConcurrent?
Concurrent是并发的意思,而QtConcurrent同std一样,是一个命名空间(namespace)。提供了一些高级的 API,使得在编写多线程的时候,无需使用低级线程原语,如读写锁,等待条件或信号。使用QtConcurrent编写的程序会根据可用的处理器内核数自动调整使用的线程数。
对于QtConcurrent真正要学习的是该命名空间下定义的函数。下面要讲的就是QtConcurrent::run函数的使用方法。
二 QtConcurrent::run()运行示例
每调用一次QtConcurrent::run()函数,就新建立一个线程。
示例1:将普通函数运行在两个不同的线程中
#include <QString>
#include <QDebug>
#include <QThread>
#include <QApplication>
#include "qtconcurrentrun.h"
QString func1()
{
qDebug()<<"我是func2函数";
}
Qstring func2(QString name)
{
qDebug() << name << "from" << QThread::currentThread();
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QFuture<QString> fut1 = QtConcurrent::run(func1);// 1.用QFuture获取该函数的运行结果
QFuture<QString> fut2 = QtConcurrent::run(func2, QString("Thread 1"));//2.参数2:向func函数传递的参数
QString result1 = fut1.result();
QString result2 = fut2.result();
fut1.waitForFinished();
fut2.waitForFinished();
}
//输出结果如下:
"Thread 1" from QThread(0x1b74fd2ebc0, name = "Thread (pooled)")
"Thread 2" from QThread(0x1b74fd534e0, name = "Thread (pooled)")
函数原型:
QFuture<T> QtConcurrent::run(Function func, ...)
示例2:成员函数
- 将类中的成员函数运行在某一个线程中,可将指向该类实例的 引用或指针 作为 QtConcurrent::run 的第一个参数传递进去;
- 常量成员函数传递常量引用 (const reference),而非常量成员函数一般传递指针 (pointer)
#include <QString>
#include <QDebug>
#include <QThread>
#include <QApplication>
#include "qtconcurrentrun.h"
class A
{
public:
A()
{
std::cout << "我是 A 的构造函数" << std::endl;
};
QString m_func(QString name)
{
m_name = name;
std::cout << "我是 A 的成员函数" << std::endl;
}
QString m_name;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QByteArray bytearray = "hello world";
A *a = new A();
QFuture<QString> fut2 = QtConcurrent::run(bytearray,&QByteArray::split,',');//1.调用QByteArray的常量成员函数split(),传递常量引用,bytearray
QFuture<QByteArray> fut3 = QtConcurrent::run(a,&A::m_func, QString("Thread 2"));//2.非常量成员函数运行在一个新的线程,传递指针
QString result2 = fut2.result();
QString result3 = fut3.result();
fut2.waitForFinished();
fut3.waitForFinished();
}
//输出结果如下:
"Thread 1" from QThread(0x1b74fd2ebc0, name = "Thread (pooled)")
"Thread 2" from QThread(0x1b74fd534e0, name = "Thread (pooled)")
示例3:线程池的应用
如果要为其指定线程池,可以将线程池的指针作为第一个参数传递进去
#include <QString>
#include <QDebug>
#include <QThread>
#include <QApplication>
#include "qtconcurrentrun.h"
using namespace QtConcurrent;
void func(QString name)
{
qDebug() << name << "from" << QThread::currentThread();
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QThreadPool pool;
pool->setMaxThreadCount(QThreadPool::globalInstance()->maxThreadCount());//setMaxThreadCount设置最大线程数,maxThreadCount()获取该计算机可运行的线程数
QFuture<void> fut1 = run(&pool,func, QString("Thread 1"));
fut1.waitForFinished();
}
函数原型:
QFuture<T> QtConcurrent::run(&pool, Function func, ...)