std::future
std::future期待一个返回,从一个异步调用的角度来说,future更像是执行函数的返回值,C++标准库使用std::future为一次性事件建模,如果一个事件需要等待特定的一次性事件,那么这线程可以获取一个future对象来代表这个事件。异步调用往往不知道何时返回,但是如果异步调用的过程需要同步,或者说后一个异步调用需要使用前一个异步调用的结果。这个时候就要用到future。
线程可以周期性的在这个future上等待一小段时间,检查future是否已经ready,如果没有,该线程可以先去做另一个任务,一旦future就绪,该future就无法复位(无法再次使用这个future等待这个事件),所以future代表的是一次性事件。
std::packaged_task
可以通过std::packaged_task对象获取任务相关联的feature,调用get_future()方法可以获得std::packaged_task对象绑定的函数的返回值类型的future。std::packaged_task的模板参数是函数签名
std::promise
从字面意思上理解promise代表一个承诺。promise比std::packaged_task抽象层次低。std::promise<T>
提供了一种设置值的方式,它可以在这之后通过相关联的std::future<T>
对象进行读取。换种说法,之前已经说过std::future可以读取一个异步函数的返回值了,那么这个std::promise就提供一种方式手动让future就绪。
示例代码:
1 #include <future> 2 #include <string> 3 #include <thread> 4 #include <iostream> 5 6 void print(std::promise<std::string>& p) 7 { 8 std::cout << "exe print" << std::endl; 9 p.set_value("There is the result whitch you want."); 10 } 11 12 int add(int a, int b) 13 { 14 std::cout << "exe add" << std::endl; 15 return a + b; 16 } 17 18 void do_some_other_things() 19 { 20 std::cout << "Hello World" << std::endl; 21 } 22 23 int main() 24 { 25 std::packaged_task<int(int, int)> task(add); 26 std::future<int> res = task.get_future(); 27 std::promise<std::string> promise; 28 task(1,1); 29 30 std::future<std::string> result = promise.get_future(); 31 std::thread t(print, std::ref(promise)); 32 std::this_thread::sleep_for(std::chrono::seconds(1)); 33 do_some_other_things(); 34 std::cout << result.get() << std::endl; 35 std::cout << res.get() << std::endl; 36 t.join(); 37 return 0; 38 }