一、概述
1、QtConcurrent模块提供了一组便捷的函数,用于在不显示创建和管理线程的情况下实现并发编程。
2、它通过将使命提交给线程池来执行,从而制止了频繁创建和烧毁线程带来的性能开销。
3、QtConcurrent非常得当处置惩罚需要并行执行的批量使命,并且能够主动管理线程和使命的分配。
二、QtConcurrent的核心功能
1、并行盘算:支持对容器(如QList、QVector)中的元素举行并行处置惩罚。
(1)QtConcurrent::map()
对容器中的每个元素应用一个函数(原地修改)
- QList list = {1, 2, 3, 4, 5};
- for (auto value : list)
- qDebug() << &list << value;
- auto future = QtConcurrent::map(list, [](int &value) { value *= 2;});
- future.waitForFinished();
- for (auto value : list)
- qDebug() << &list << value;
- //结果
- 0xf5949ff688 1
- 0xf5949ff688 2
- 0xf5949ff688 3
- 0xf5949ff688 4
- 0xf5949ff688 5
- 0xf5949ff688 2
- 0xf5949ff688 4
- 0xf5949ff688 6
- 0xf5949ff688 8
- 0xf5949ff688 10
复制代码 (2)QtConcurrent::mapped()
对容器中的每个元素应用一个函数,并返回一个新的容器
- int convert(int value)
- {
- return value * 2;
- }
- QList<int> list = {1, 2, 3, 4, 5};
- for (auto value : list)
- qDebug() << &list << value;
- auto future = QtConcurrent::mapped(list, convert);
- future.waitForFinished();
- QList<int> result = future.results();
- for (auto value : result)
- qDebug() << &result << value;
- //结果
- 0xda6f18fbe0 1
- 0xda6f18fbe0 2
- 0xda6f18fbe0 3
- 0xda6f18fbe0 4
- 0xda6f18fbe0 5
- 0xda6f18fc08 2
- 0xda6f18fc08 4
- 0xda6f18fc08 6
- 0xda6f18fc08 8
- 0xda6f18fc08 10
复制代码 (3)Qt::Concurrent::filter()
过滤容器中的元素(原地修改)
- QList<int> list = {1, 2, 3, 4, 5};
- for (auto value : list)
- qDebug() << &list << value;
- auto future = QtConcurrent::filter(list, [](int value) { return value % 2 == 0;});
- future.waitForFinished();
- for (auto value : list)
- qDebug() << &list << value;
- //运行结果
- 0xd8871f9c8 1
- 0xd8871f9c8 2
- 0xd8871f9c8 3
- 0xd8871f9c8 4
- 0xd8871f9c8 5
- 0xd8871f9c8 2
- 0xd8871f9c8 4
复制代码 2、使命分发:支持将函数或方法分发到线程池中执行
(1)QtConcurrent::run()
将函数分发到线程池中执行,不会阻塞当前线程;
返回一个QFuture对象,用于获取使命的执行效果或监视使命状态
支持普通函数、Lambda表达式、成员函数等多种调用方式
- int add(int a, int b)
- {
- qDebug() << "Task running in thread" << QThread::currentThreadId();
- return a + b;
- }
- void print()
- {
- QThread::sleep(2);
- qDebug() << "Task print in thread" << QThread::currentThreadId();
- }
- class MyClass
- {
- public:
- void function()
- {
- qDebug() << "Task function in thread" << QThread::currentThreadId();
- }
- };
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- qDebug() << "start";
- //无参调用
- QtConcurrent::run(print);
- //有参调用
- QtConcurrent::run(add, 3, 4);
- //Lambda表达式
- QtConcurrent::run([](int a, int b){
- qDebug() << "Task Lambda in thread" << QThread::currentThreadId();
- return a + b;
- }, 2, 3);
- //成员函数
- MyClass test;
- QtConcurrent::run(&test, &MyClass::function);
-
- qDebug() << "end";
- return a.exec();
- }
- //结果
- start
- end
- Task function in thread 0x6c38
- Task running in thread 0x8fd0
- Task print in thread 0x4a28
复制代码 3、异步编程:支持异步执行使命,并通过信号与槽机制通知使命完成
(1)QFuture:QFuture的效果查询函数,都是阻塞型的,会等待QtConcurrent::run()竣事
表示异步盘算的效果,可以通过result()或results()获取盘算效果,支持等待使命完成(waitForFinished());
- int getCount(int n)
- {
- int i = 0;
- while (i < n)
- {
- qDebug() << i;
- QThread::sleep(1);
- ++i;
- }
- }
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- qDebug() << "start";
- QFuture<int> future = QtConcurrent::run(getCount, 4);
- qDebug() << future.result() << future.resultCount(); //会阻塞线程
- qDebug() << "end";
- return a.exec();
- }
- //结果
- start
- 0
- 1
- 2
- 3
- -1 1
- end
复制代码 (2)QFutureWatcher:用于监视QFuture的状态,通过信号与槽机制通知使命完成、进度更新等
QFuture类本身未继承QObject,以是没法直接使用信号槽,以是需要另一个监视类QFutureWatcher。
- int getCount(int n)
- {
- int i = 0;
- while (i < n)
- {
- qDebug() << i;
- QThread::sleep(1);
- ++i;
- }
- return -1;
- }
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- qDebug() << "start";
- QFuture<int> future = QtConcurrent::run(getCount, 4);
- QFutureWatcher<int> watcher;
- watcher.setFuture(future);
- QObject::connect(&watcher, &QFutureWatcher<int>::finished, [&](){
- qDebug() << QThread::currentThreadId() << future.result() << future.resultCount();
- });
- qDebug() << "end";
- return a.exec();
- }
- //结果
- start
- 0
- QFutureWatcher::connect: connecting after calling setFuture() is likely to produce race
- end
- 1
- 2
- 3
- 0x8818 -1 1
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |