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;
}
我有一个这样的代码,其函数 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;
}