并发运行

QtConcurrent :: run()函数在一个单独的线程中运行一个函数。该函数的返回值可通过QFuture API获得。

此函数是Qt Concurrent框架的一部分。

在单独的线程中运行函数

要在另一个线程中运行函数,请使用QtConcurrent :: run():

extern void aFunction();
QFuture<void> future = QtConcurrent::run(aFunction);

aFunction将会在一个从默认的QThreadPool中获得的单独线程中运行,您可以使用QFuture和QFutureWatcher类来监视函数的状态。

要使用专用线程池,可以将QThreadPool作为第一个参数传递:

extern void aFunction();
QThreadPool pool;
QFuture<void> future = QtConcurrent::run(&pool, aFunction);

将参数传递给函数

函数的参数按顺序追加在函数名后即可将参数传递给函数,例如:

extern void aFunctionWithArguments(int arg1, double arg2, const QString &string);

int integer = ...;
double floatingPoint = ...;
QString string = ...;

QFuture<void> future = QtConcurrent::run(aFunctionWithArguments, integer, floatingPoint, string);
A copy of each argument is made at the point where QtConcurrent::run() is called, 
and these values are passed to the thread when it begins executing the function. 
Changes made to the arguments after calling QtConcurrent::run() are not visible to the thread.

当QtConcurrent :: run()被调用时,每个参数都被复制了一份,并且将这些复制后的值在被运行的函数开始被运行时传递给被运行函数。调用QtConcurrent :: run()后对参数所做的更改对于当前线程是不可见的。(不知道翻译的是否正确)

从函数返回值

函数的任何返回值都可以通过QFuture获得:

extern QString functionReturningAString();
QFuture<QString> future = QtConcurrent::run(functionReturningAString);
...
QString result = future.result();

如上所述,传递参数的方式如下:

extern QString someFunction(const QByteArray &input);

QByteArray bytearray = ...;

QFuture<QString> future = QtConcurrent::run(someFunction, bytearray);
...
QString result = future.result();

请注意,QFuture :: result()函数会阻塞线程并等待结果可用。当函数执行完毕且结果可用时,使用QFutureWatcher获取通知。

其他API功能

使用成员函数
QtConcurrent :: run()也接受指向成员函数的指针。第一个参数必须是const引用或指向该类实例的指针。在调用const成员函数时,通过const引用传递是很有用的。传递指针对于调用修改实例的非const成员函数很有用。

例如,在单独的线程中调用QByteArray :: split()(一个const成员函数)就像这样:

// call 'QList<QByteArray> QByteArray::split(char sep) const' in a separate thread
QByteArray bytearray = "hello world";
QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split, ',');
...
QList<QByteArray> result = future.result();

调用非const成员函数是这样的:

// call 'void QImage::invertPixels(InvertMode mode)' in a separate thread
QImage image = ...;
QFuture<void> future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba);
...
future.waitForFinished();
// At this point, the pixels in 'image' have been inverted

使用Lambda函数
调用lambda函数是这样的:

QFuture<void> future = QtConcurrent::run([=]() {
   
    // Code in this block will run in another thread
});
...