Concurrent Run
The QtConcurrent::run() 的作用在独立线程允许一个函数. 函数的返回值通过 QFuture API获取.
这个函数是 Qt Concurrent 框架的一部分.
在独立线程中运行一个函数
想让一个函数在另一个线程运行, 使用QtConcurrent::run():
extern void aFunction(); QFuture<void> future = QtConcurrent::run(aFunction);
aFunction 运行在从 QThreadPool中获取的独立线程. 你可以使用 QFuture 和 QFutureWatcher 监控函数状态.
如果想使用特定的线程池, 你可以将 QThreadPool 对象作为参数传递给QtConcurrent::run():
extern void aFunction(); QThreadPool pool; QFuture<void> future = QtConcurrent::run(&pool, aFunction);
给函数传递参数
如果想给函数传递参数, 你可以将参数紧跟在函数名之后, 传递给 QtConcurrent::run(). 例如:
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);
参数以副本的形式传递给QtConcurrent::run(), 这些参数在线程开始调用函数时传递给线程. 调用 calling 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() f函数是阻塞函数, 结果可用时返回. 结果使用 QFutureWatcher 获取.
Additional API Features
Using Member Functions
QtConcurrent::run() also accepts pointers to member functions. The first argument must be either a const reference or a pointer to an instance of the class. Passing by const reference is useful when calling const member functions; passing by pointer is useful for calling non-const member functions that modify the instance.
For example, calling QByteArray::split() (a const member function) in a separate thread is done like this:
// 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();
Calling a non-const member function is done like this:
// 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
Using Lambda Functions
Calling a lambda function is done like this:
QFuture<void> future = QtConcurrent::run([=]() { // Code in this block will run in another thread }); ...