qt 线程实现的三种方法

一、简介
QtConcurrent这是一个高级 API,构建于QThreadPool之上,它提供更高层次的函数接口(APIs),使所写的程序,可根据计算机的CPU核数,自动调整运行的线程数量。通常用于处理大多数通用的并行计算模式。
注意,QtConcurrent是一个命名空间而不是一个类,因此其中的所有函数都是命名空间内的全局函数。

二、使用方法
1. 添加concurrent
从Qt4.4之后,QtConcurrent从core模块中独立出来,作为单独的模块。
所以先要在.pro中添加 QT += concurrent

QT       += core gui concurrent
1
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;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
运行如下:

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")
1
2
3
4
5
6
三、Qt多线程三种方法总结


四、不同开发场景下的考虑
需要线程的生命周期    开发场景    解决方案
单次调用    在其他的线程中运行一个方法,当方法运行结束后退出线程。    (1)编写一个函数,然后利用 QtConcurrent::run()运行它;(2)从QRunnable 派生一个类,并利用全局线程池QThreadPool::globalInstance()->start()来运行它。(3) 从QThread派生一个类, 重载QThread::run() 方法并使用QThread::start()来运行它。
单次调用    一个耗时的操作必须放到另一个线程中运行。在这期间,状态信息必须发送到GUI线程中。    使用 QThread,,重载run方法并根据情况发送信号。.使用queued信号/槽连接来连接信号与GUI线程的槽。
常驻    有一对象位于另一个线程中,将让其根据不同的请求执行不同的操作。这意味与工作者线程之间的通信是必须的。    从QObject 派生一个类并实现必要的槽和信号,将对象移到一个具有事件循环的线程中,并通过queued信号/槽连接与对象进行通信。
关于多线程QRunnable的用法,可以参考我的另一篇博客Qt多线程的三种方法之一QThread
关于多线程QConcurrent的用法,可以参考我的另一篇博客Qt多线程的三种方法之二QtConcurrent::run()+QThreadPool
————————————————
版权声明:本文为CSDN博主「苏克贝塔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41761608/article/details/119328018

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT,有几种方法可以新建线程。一种方法是继承QThread类,然后重写run方法。在这种方法,除了run方法之外的所有操作都是在主线程执行的。另一种方法是使用moveToThread将新建线程转移到继承QObject的新类实例。这种方法,所有的成员函数都是在线程执行的。还有一种方法是继承QRunnable类,重新实现run函数,并结合QThreadPool实现线程池。在这种方法,可以通过构建一个本地的线程池,并设置最大线程数来控制线程执行。\[1\]\[2\] 另外,还有两种方法是继承QThread类并重写run函数,以及继承QObject类并调用moveToThread函数。这两种方法不需要继承类,可以直接将需要执行函数放到线程运行。在第一种方法,可以通过调用start函数启动线程,并自动调用run函数。可以使用isRunning函数判断线程是否已启动,使用terminate函数终止线程,使用wait函数等待线程终止。在第二种方法,可以通过调用moveToThread函数将对象移动到新线程执行。\[3\] #### 引用[.reference_title] - *1* [QT新建线程的几种方法](https://blog.csdn.net/li3781695/article/details/88233286)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Qt开启线程的五种方法](https://blog.csdn.net/m0_73443478/article/details/129556890)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值