Concurrent Run

The QtConcurrent::run() 的作用在独立线程允许一个函数. 函数的返回值通过 QFuture API获取.

这个函数是 Qt Concurrent 框架的一部分.

在独立线程中运行一个函数

想让一个函数在另一个线程运行, 使用QtConcurrent::run():


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

aFunction 运行在从 QThreadPool中获取的独立线程. 你可以使用 QFutureQFutureWatcher 监控函数状态.

如果想使用特定的线程池, 你可以将 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
  });
  ...