QT多线程之QtConcurrent::run()

2022年4月1日 350点热度 1人点赞 0条评论

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()保证线程执行完毕。

示例

.h 文件

#pragma once
#include <QtCore/QObject>
#include <QtConcurrent/QtConcurrent>
#include <QtCore/QThread>
class ThreadTest {
public:
    ThreadTest();
    ~ThreadTest() = default;
    
public:
    void anotherThread();
    std::string anotherThreadReturn();
};

.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";
}

新建对象后的输出结果:

main thread ID: 000000000000499C
Normal function thread ID: 0000000000007830
Another thread ID: 0000000000006BA4
Another return thread ID: 0000000000000A2C
anotherThreadReturn result: This is result

总结

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

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

大脸猫

这个人虽然很勤快,但什么也没有留下!

文章评论