std::future , std::promise and Returning values from Thread

std::future, std::promise and Returning values from Thread

std::future对象常与异步一起使用。本文将主要关注使用std::future与std::promise。

一般情况下,我们希望一个线程能够返回一个结果。假设这样的一个场景,我们的应用创建一个线程去压缩文件夹,然后我们希望得到返回的zip包名和大小。

  1. 老的方法:在多个线程之间通过指针共享数据

往新的线程传递进指针,该线程将会设置其中的数据。然后在主线程中继续使用条件变量进行等待,当新线程设置数据并发出条件变量信号时,主线程将被唤醒并从该指针获取数据。

这种方法使用了一个条件变量、一个互斥锁和一个指针。但假如我们希望这个线程在不同的时间点返回三个不同的值,问题就变得复杂了。一个简单的方法是使用std::future。

  1. c++11的方法:使用std::future和std::promise

std::future是一个类模版,对象存储的是future value——一个在内部存储中将在未来分配的值,提供了get()访问,但在这个未来值不可用时,调用get()将会阻塞。

std::promise也是一个类模版,它的对象承诺将来会设置值,每个对象都有一个关联的std::future对象。一个std::promise对象与关联的std::future对象共享数据。

使用方法

  1. 首先在线程1创建std::promise对象,该对象将传到线程2以便设置值
1
std::promise<int> promiseObj;
  1. 在将promiseObj从线程1传递给线程2之前,可以先获得一个关联的future值
1
std::future<int> futureObj = promiseObj.get_future();
  1. 将promiseObj传递给线程2
  2. 线程1尝试去获取线程2设置的值
1
int val = futureObj.get();
  1. 在线程2设置值之前,线程1会阻塞住
1
promiseObj.set_value(45);
img

注意

如果在设置值之前销毁了std::promise对象,则关联的std::future对象调用get将会抛出异常。

如果希望线程在不同的时间点返回多个值,那么只需要在线程中传递多个std::promise对象。