首页 > 其他分享 >Qt - 多线程之QtConcurrent::run()

Qt - 多线程之QtConcurrent::run()

时间:2023-10-25 11:55:50浏览次数:39  
标签:调用 run 函数 QtConcurrent include 线程 多线程

QT多线程之QtConcurrent::run()

QT有几种可以实现多线程编程的方式,其中最方便使用,最便携的一定是QtConcurrent::run()了,这是一个模板函数,有很多的重载原型。

//在新的线程中调用普通函数 
template <typename T> QFuture<T> QtConcurrent::run(Function function, ...) 

//使用线程池中的线程调用普通函数 
template <typename T> QFuture<T> QtConcurrent::run(QThreadPool *pool, Function function, ...) 

//在新的线程里调用成员函数 有多个重载实现不同的参数个数 
template <typename T> QFuture<T> QtConcurrent::run(className *obejct, Function function, ...)

这些模板都有多个重载,支持带参数函数,切可以带多个参数。

QFuture 也是一个模板类,它可以监控线程的运行状态有,并可以获取在另一个线程中运行的函数的返回值,返回值通过调用result()函数获取。

需要注意的是获取返回值之前,最好先调用waitForFinished()保证线程执行完毕。

示例

QtThreadTest.h

#pragma once
#include <QtCore/QObject>
#include <QtConcurrent/QtConcurrent>
#include <QtCore/QThread>

class ThreadTest 
{
public:
    ThreadTest();
    ~ThreadTest() = default;

public:
    void anotherThread();
    std::string anotherThreadReturn();
};

QtThreadTest.cpp

#include "QtThreadTest.h"
#include <iostream>
#include <QFuture>

void normalFunction() 
{
    std::cerr << "Normal function thread ID: " << QThread::currentThreadId() << std::endl;
}

ThreadTest::ThreadTest()
{
    std::cerr << "main thread ID: " << QThread::currentThreadId() << std::endl;
    QtConcurrent::run(normalFunction);
    QFuture<void> future = QtConcurrent::run(this, &ThreadTest::anotherThread);
    QFuture<std::string> future1 = QtConcurrent::run(this, &ThreadTest::anotherThreadReturn);
    future.waitForFinished();
    future1.waitForFinished();

    std::cerr << "anotherThreadReturn result: " << future1.result() << std::endl;
}

void ThreadTest::anotherThread()
{
    std::cerr << "Another thread ID: " << QThread::currentThreadId() << std::endl;
}

std::string ThreadTest::anotherThreadReturn()
{
    std::cerr << "Another return thread ID: " << QThread::currentThreadId() << std::endl;
    return "This is result";
}

输出结果:

总结

  1. 调用run() 之后,函数不一定会被立即执行,如果有多个run()被调用,函数的调用顺序不一定是run()的调用顺序,这些都和线程的调度有关系。
  2. run(function) 实际上等价于run(QThreadPool::globalInstance(),function)

如果只是简单的想在其他线程中调用某个函数,不需要复杂的数据同步,那么QtConcurrent::run() 相比其他实现多线程的方式绝对是不二之选。

 

2022-11-1 补充

之前因为看漏了文档,导致今天被自己坑了一把。

文档中提到,Run中的函数参数,都是拷贝之后使用副本,如果在线程中调用的函数参数类型是引用类型,那么是不能正常对原有的变量进行改变的。

比如下面的例子

 
void refrencesPar(int& a, int& b)
{
    a = 1;
    b = 1;
    std::cerr << "call  refrencesPar()    " << "a : " << a << ",b: " << b << 
        "   |a address:" << &a << "  |b address: " << &b <<std::endl;
}

ThreadTest::ThreadTest()
{
    int a = 0, b = 0;
    auto future = QtConcurrent::run(refrencesPar, a, b);
    future.waitForFinished();
    std::cerr << "a : " << a << ",b: " << b <<"   |a address:" << &a << "  |b address: " << &b << std::endl;
}

运行代码输出的结果:

可以看到,两次输出的a,b变量的地址是不一样的,因为run在调用函数之前已经拷贝了一份副本,所以如果想在函数中改变外面变量的值,这里只能使用指针。

 

标签:调用,run,函数,QtConcurrent,include,线程,多线程
From: https://www.cnblogs.com/zhuchunlin/p/17786799.html

相关文章

  • Unity ILRuntime 实战教程系列
    1.1 Unity 搭建ILRuntime开发环境 Unity热更新目前主流的方案有; Lua, ILRuntime, puerts, huatuo方案。前两个大家都比较熟悉了,puerts是基于TypeScript开发的热更新,huatuo是基于C#的方案。后两个大家会比较陌生。本系列分享基于ILRuntime来做热更新。 ILRuntime热更......
  • Runner GoUI自动化测试发布
    构建自动化测试体系是当下每个项目团队愿意去做的,自动化测试减少重复操作节省人力成本。RunnerGoUI自动化平台RunnerGo提供从API管理到API性能再到可视化的API自动化、UI自动化测试功能模块,覆盖了整个产品测试周期。RunnerGoUI自动化基于Selenium浏览器自动化方案构建,内嵌高度可......
  • Runner GoUI自动化测试发布
    构建自动化测试体系是当下每个项目团队愿意去做的,自动化测试减少重复操作节省人力成本。RunnerGoUI自动化平台RunnerGo提供从API管理到API性能再到可视化的API自动化、UI自动化测试功能模块,覆盖了整个产品测试周期。RunnerGoUI自动化基于Selenium浏览器自动化方案构建,内嵌高......
  • 升讯威在线客服系统的并发高性能数据处理技术:为多线程处理同步数据
    我在业余时间开发维护了一款免费开源的升讯威在线客服系统,也收获了许多用户。对我来说,只要能获得用户的认可,就是我最大的动力。最近客服系统成功经受住了客户现场组织的压力测试,获得了客户的认可。客户组织多名客服上线后,所有员工同一时间打开访客页面疯狂不停的给在线客服发消......
  • LoadRunner参数配置
    参数配置:参数配置:一、如何选择下一个值Sequential:顺序Random:随机Unique:唯一二、如何更新值Eachiteration:迭代更新Eachoccurrence:值出现则更新Once:更新一次三、当超出值在一中选择Unique的时候可以配置第三个AboutVuser:报错Continue inacyclicmanner:循环Con......
  • 在C++中,互斥变量(std::mutex)是用于保护共享资源的重要工具,但它们确实有一些局限性,其中
    在C++中,互斥变量(std::mutex)是用于保护共享资源的重要工具,但它们确实有一些局限性,其中之一是无法保证包含指针的区域的多线程安全。这是因为互斥锁本质上只能保护它们所保护的代码块,而不会考虑指针指向的数据。下面是一些与互斥锁和指针相关的常见问题和注意事项:共享数据的复制:......
  • Java使用多线程异步执行批量更新操作方法
    一、核心技术Java提供了Executor框架来实现多线程任务的执行。我们可以通过创建ExecutorService对象来管理线程池,然后将任务提交给这个线程池执行。Executor框架的优点在于,它可以自动管理线程数量,以最大化利用CPU和内存资源。二、具体实现方法1、创建一个数据更新任务类,实现Run......
  • RuntimeError: “nll_loss_forward_reduce_cuda_kernel_2d_index“ not implemented f
    RuntimeError:"nll_loss_forward_reduce_cuda_kernel_2d_index"notimplementedfor'Int'Traceback(mostrecentcalllast):File"E:/MyWorkspace/EEG/Pytorch/Train.py",line79,in<module>opti='Adam')......
  • 杰哥教你面试之一百问系列:java多线程
    java多线程是java面试中的高频问题,如何才能在面试中脱颖而出呢?熟读这里的一百个java多线程面试问题即可。1.什么是线程?什么是进程?回答:线程是操作系统能够进行调度的最小执行单位,它包含在进程中,共享进程的资源。进程是一个正在执行中的程序,它包含了代码、数据和系统资源。一个进程......
  • 笔记:Qt开发之多线程同步互斥机制
    目标:了解Qt多线程开发中常用的同步互斥类,使用场景和特点 实现线程互斥和同步常用的类互斥锁:QMute、QMutexLocker条件变量:QWaitCondition信号量:QSemaphore读写锁:QReadLocker、QWriteLocker、QReadWriteLock 1,QMutex特点:QMutex是Qt框架提供的互斥锁类,用于保护共享资......