Qt循环调用线程

Qt calling threads in a loop

我有一个这样的代码,其函数 double myfunction(double) 需要很长时间才能完成。

使用 Qt (https://doc.qt.io/qt-5/qtconcurrentrun.html),我如何 运行 循环利用一个线程为每个 myfunction 调用减少计算时间?这有意义吗?

std::vector<double> parameters;        //vector full of input values
std::vector<double> results;           //vector to store results in

for(uint i=0; i<parameters.size(); i++)
{
   double parameter = parameters.at(i);
   double result = myfunction(parameter);
   results.push_back(result);
}

对于您自己的情况,QtConcurrent::run 的一个简单示例用法类似于(未测试)...

std::vector<double> parameters;     // vector full of input values.
std::vector<double> results;        // Empty vector to store results.

/*
 * Each call to QtConcurrent::run returns a QFuture.  Store
 * these so we can wait on the results.
 */
std::vector<QFuture<double>> futures;

/*
 * Start all tasks and store the QFutures.
 */
for (auto parameter: parameters) {
    futures.push_back(QtConcurrent::run(&myfunction, parameter));
}

/*
 * Wait for each QFuture in turn and save its result.
 */
for (auto &f: futures) {
    results.push_back(f.result());
}

使用 QtConcurrent::mapped()QFutureWatcher 以便所有处理异步发生。

当所有处理完成时,

QFutureWatcher 发出一个 finished() 信号。结果由 QFutureWatcher 管理的单个 QFuture 累积。最重要的是,UI 永远不会冻结。

my_project.pro:

# must include "concurrent" to use QtConcurrent::mapped()
QT += concurrent
...

MappedProcessor.h:

#include <QObject>
#include <QFutureWatcher>
#include <vector>

class MappedProcessor : public QObject
{
    Q_OBJECT
public:
    explicit MappedProcessor(QObject *parent = nullptr);

public slots:
    void processValues();

private slots:
    void handleProcessingFinished();

private:
    static double myFunction(double value);

    QFutureWatcher<double> m_futureWatcher;
};

MappedProcessor.cpp:

#include "MappedProcessor.h"
#include <QtConcurrent/QtConcurrent>
#include <QList>
#include <QThread>

MappedProcessor::MappedProcessor(QObject *parent) : QObject(parent)
{
    connect(&m_futureWatcher, &QFutureWatcher<double>::finished,
            this, &MappedProcessor::handleProcessingFinished);
}

void MappedProcessor::processValues()
{
    // create some values to process
    std::vector<double> parameters;
    for (auto i = 0; i < 16; ++i)
        parameters.push_back(i);

    auto sequence = QVector<double>::fromStdVector(parameters);
    auto future = QtConcurrent::mapped(sequence, myFunction);
    m_futureWatcher.setFuture(future);
}

void MappedProcessor::handleProcessingFinished()
{
    // convert the results to std::vector<double>
    auto theResults = m_futureWatcher.future().results().toVector().toStdVector();

    qDebug() << "Received" << theResults.size() << "results";
}

// pretend to be a long running calculation...
double MappedProcessor::myFunction(double value)
{
    QThread::msleep(10000);
    return value;
}