QtConcurrent::run()多线程的同步、异步 QFutureSynchronizer

本文介绍了Qt中的QtConcurrent模块,包括其提供的QFuture、QFutureWatcher和QFutureSynchronizer类,展示了如何进行并行计算、异步和同步操作,以及如何使用lambda表达式。重点讲解了QFuture的相关注意事项和QtConcurrent::map等函数的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Qt 提供了 QtConcurrent 模块,处理一些常见的并行计算,最大的特点就是无需再使用互斥锁这种很低级的操作,全都封装好了。除此以外,QFuture、QFutureWatcher、QFutureSynchronizer 类提供了一些辅助性的操作;简单实现了子线程同步、异步操作;

QtConcurrent::run() 需注意

  • 默认扔进了全局线程池,即 QThreadPool::globalInstance()
  • 传参数的时候,都会复制一份副本。即使参数是引用,在函数中修改数据也不会对源对象产生任何影响。
  • QFuture::result() 与 QFuture::waitForFinished()函数都会阻塞,直到结果可用才继续之后的代码。
  • QtConcurrent::run()返回的QFuture不支持取消、暂停和进度报告。返回的QFuture只能用于查询运行/完成状态和函数的返回值。

 可以执行无参、含参、有返回值函数,以及lambda表达式

函数原型:

QFuture<T> QtConcurrent::run(Function function, ...)
QFuture<T> QtConcurrent::run(QThreadPool *pool, Function function, ...)

默认全局线程池。

【QFuture】同步

QFuture::result()

样例:

  int add(int &num)
   {
        return ++num;
   }
  
  
  QFuture<int> future = QtConcurrent::run(add, 1);
  future.waitForFinished();
  
  qDebug() << "result: " << future.result();

【QFutureWatcher】异步

若不想一直等待结果,可以使用QFutureWatcher获取通知。

// 实例化对象,并连接到 finished() 信号。
MyClass myObject;
QFutureWatcher<int> watcher;
connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished()));
 
// 开始计算
QFuture<int> future = QtConcurrent::run(...);
watcher.setFuture(future);

     if(nullptr == WidgetWatcher)
    {
        WidgetWatcher = new QFutureWatcher<void>;
        connect(WidgetWatcher, &QFutureWatcher<void>::finished, this, [=]() {
 
            qDebug()<<"finish threadid "<<QThread::currentThreadId();
             mQProgressDialog->close();
        });
    }
 
    QFuture<void> future = QtConcurrent::run([=]() {
        //slotShowInsertionWidget();
        qDebug()<<"111 threadid "<<QThread::currentThreadId();
        QThread::sleep(3);
        getTextStaticFun();
    });
    WidgetWatcher->setFuture(future);

详细见:C++11 Qt QFutureWatcher lambda_qfuturewatcher获取几个future-CSDN博客

【QFutureSynchronizer】同步

QFutureSynchronizer 类是一个简化QFuture同步的便捷类。QFutureSynchronizer是一个模板类,它简化了一个或多个QFuture对象的同步。使用 addFuture() 或 setFuture() 函数添加 Future 。

   futures():返回一个Futures 列表。

   clearFutures() 从 QFutureSynchronizer 中删除所有的Future 。

传入参数名和参数;获取结果

  int add(int &num)
   {
        return ++num;
   }
  
  
QFutureSynchronizer<qulonglong> synchronizer;
synchronizer.addFuture(QtConcurrent::run(add, 50));
synchronizer.addFuture(QtConcurrent::run(add, 100));
synchronizer.waitForFinished();
qDebug() << "第51个 数: " << synchronizer.futures()[0].result();
qDebug() << "第101个数: " << synchronizer.futures()[1].result();
成员函数

1、~QFutureSynchronizer()

    会调用 waitForFinished() 函数以确保在销毁之前所有QFuture都已完成。

2、void addFuture(const QFuture<T> &future)

    将QFuture添加到托管列表中。

3、bool cancelOnWait()

    是否启用了等待取消功能。

4、void clearFutures()

    清空QFuture托管列表。

5、QList<QFuture<T> > futures()

    获取托管列表。

6、void setCancelOnWait(bool enabled)

    启用或禁用等待取消功能。如果 enabled 为 true,waitForFinished() 函数将在等待它们完成之前取消所有QFuture。

7、void setFuture(const QFuture<T> &future)

    将 future 设置为唯一管理的QFuture。

8、void waitForFinished()

     等待所有QFuture完成。 如果 cancelOnWait() 返回 true,则在等待它们完成之前取消所有QFuture。

QtConcurrent::map()

QtConcurrent::map()、QtConcurrent::mapped() 和 QtConcurrent::mappedReduced() 函数对一个序列中(例如:QList、QVector)的项目并行地进行计算。

map函数的功能是在其他线程运行指定的函数,map函数有两个参数

第一个是集合

第二个参数是一个函数。它的作用就是同时用第二个参数来计算第一个参数中的每一个元素,且结果直接覆盖到元素中,如果是成员函数,那要静态成员函数才能运行

//静态函数
void Widget::Func(QPushButton * & btn)
 {
     QTime time = QTime::currentTime();
    qsrand(time.msec() + time.second()*1000);
     btn->setText(QString("按钮_%1").arg(qrand() % 20));
     qDebug()<<"thread ID"<<QThread::currentThreadId();
}
 
void Widget::on_pushButton_clicked()
{
     QList<QPushButton*> list = this->findChildren<QPushButton*>();
    QFuture<void> f = QtConcurrent::map(list,&Widget::Func); //map函数 不能运行非静态成员函数
    f.waitForFinished();
}
mapped函数

mapped函数的作用和map类似,只是把计算结果放到了新的容器中

int func2(int a)
{
    return a + 1;
}
 
 void Widget::on_pushButton_clicked()
  {
      QList<int> alist;
    alist<<1<<3<<5<<7<<9;

     QFuture<int> f = QtConcurrent::mapped(alist,func2); //QFuture的类型为int
     f.waitForFinished();
    qDebug()<<"alist"<<alist;
    QList<int> newlist = f.results();
     qDebug()<<"newlist"<<newlist;

}

输出:

main thread x3958
alist(1,3,5,7,9)
newlist(2,4,6,8,10)
mappedReduced函数

mappedReduced函数比mapped多一个参数,这个参数也是个函数。作用就是将mapped出来的结果再计算最终得出一个值

 int func3(int a)
 {
     return a + 1;
 }
  
 void sum(int& result, const int& b)
  {
      result += b;
  }
 
void Widget::on_pushButton_clicked()
 {
     QList<int> alist;
    alist<<1<<3<<5<<7<<9;
  
     QFuture<int> result = QtConcurrent::mappedReduced(alist,func3,sum);
    result.waitForFinished();
     qDebug()<<result.result();
 }

alist中的一个值执行完func3马上执行sum,而不是alist中所有之都执行完才执行sum。

结果:30

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恋恋西风

up up up

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值