类模板 std::future 提供访问异步操作结果的机制:(通过 std::async 、 std::packaged_task 或 std::promise 创建的)异步操作能提供一个 std::future 对象给该异步操作的创建者。然后,异步操作的创建者能用各种方法查询、等待或从 std::future 提取值。若异步操作仍未提供值,则这些方法可能阻塞。异步操作准备好发送结果给创建者时,它能通过修改链接到创建者的 std::future 的共享状态(例如 std::promise::set_value )进行。
注意, std::future 所引用的共享状态不与另一异步返回对象共享(与 std::shared_future 相反)。
—摘抄自https://www.apiref.com/cpp-zh/cpp/thread/future.html
这是官方的定义,那我们就看下具体std::future是怎么回事和怎么使用的吧。
std::future头文件如下:
#include
std::future作用是希望线程返回一个结果,用于异步的操作。
下面,首先看下std::__basic_future 的定义:
/// Common implementation for future and shared_future. templateclass __basic_future : public __future_base { protected: typedef shared_ptr<_State_base> __state_type; typedef __future_base::_Result<_Res>& __result_type; private: __state_type _M_state; public: // Disable copying. __basic_future(const __basic_future&) = delete; __basic_future& operator=(const __basic_future&) = delete; bool valid() const noexcept { return static_cast (_M_state); } void wait() const { _State_base::_S_check(_M_state); _M_state->wait(); } template future_status wait_for(const chrono::duration<_Rep, _Period>& __rel) const { _State_base::_S_check(_M_state); return _M_state->wait_for(__rel); } template future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const { _State_base::_S_check(_M_state); return _M_state->wait_until(__abs); } protected: /// Wait for the state to be ready and rethrow any stored exception __result_type _M_get_result() const { _State_base::_S_check(_M_state); _Result_base& __res = _M_state->wait(); if (!(__res._M_error == 0)) rethrow_exception(__res._M_error); return static_cast<__result_type>(__res); } void _M_swap(__basic_future& __that) noexcept { _M_state.swap(__that._M_state); } // Construction of a future by promise::get_future() explicit __basic_future(const __state_type& __state) : _M_state(__state) { _State_base::_S_check(_M_state); _M_state->_M_set_retrieved_flag(); } // Copy construction from a shared_future explicit __basic_future(const shared_future<_Res>&) noexcept; // Move construction from a shared_future explicit __basic_future(shared_future<_Res>&&) noexcept; // Move construction from a future explicit __basic_future(future<_Res>&&) noexcept; constexpr __basic_future() noexcept : _M_state() { } struct _Reset { explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { } ~_Reset() { _M_fut._M_state.reset(); } __basic_future& _M_fut; }; };
之后就是我们可以看到,std::future是继承std::__basic_future的,具体的定义如下:
/// Primary template for future. templateclass future : public __basic_future<_Res> { friend class promise<_Res>; template friend class packaged_task; template friend future ::type> async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res> _base_type; typedef typename _base_type::__state_type __state_type; explicit future(const __state_type& __state) : _base_type(__state) { } public: constexpr future() noexcept : _base_type() { } /// Move constructor future(future&& __uf) noexcept : _base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) noexcept { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value _Res get() { typename _base_type::_Reset __reset(*this); return std::move(this->_M_get_result()._M_value()); } shared_future<_Res> share(); }; /// Partial specialization for future template class future<_Res&> : public __basic_future<_Res&> { friend class promise<_Res&>; template friend class packaged_task; template friend future ::type> async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res&> _base_type; typedef typename _base_type::__state_type __state_type; explicit future(const __state_type& __state) : _base_type(__state) { } public: constexpr future() noexcept : _base_type() { } /// Move constructor future(future&& __uf) noexcept : _base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) noexcept { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value _Res& get() { typename _base_type::_Reset __reset(*this); return this->_M_get_result()._M_get(); } shared_future<_Res&> share(); }; /// Explicit specialization for future template<> class future : public __basic_future { friend class promise ; template friend class packaged_task; template friend future ::type> async(launch, _Fn&&, _Args&&...); typedef __basic_future _base_type; typedef typename _base_type::__state_type __state_type; explicit future(const __state_type& __state) : _base_type(__state) { } public: constexpr future() noexcept : _base_type() { } /// Move constructor future(future&& __uf) noexcept : _base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) noexcept { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value void get() { typename _base_type::_Reset __reset(*this); this->_M_get_result(); } shared_future share(); };
在C11中,std::future有两种类型的模板。
1、唯一期望值unique futures, std::future<> std::future的实例只能关联一个事件。
2、共享期望值shared futures, std::shared_future<> std::shared_future可以关联多个事件。
异步执行的三种状态如下:
/// Status code for futures
enum class future_status
{
ready,//异步操作已经完成
timeout,//异步操作超时
deferred//异步操作还没有开始
};
这是基本的std::future的定义,下面我们需要看下std::async的定义。
std::async用于启动一个异步执行策略
/// async templatefuture ::type> async(launch __policy, _Fn&& __fn, _Args&&... __args) { typedef typename result_of<_Fn(_Args...)>::type result_type; std::shared_ptr<__future_base::_State_base> __state; if ((__policy & (launch::async|launch::deferred)) == launch::async) { __state = __future_base::_S_make_async_state(std::__bind_simple( std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); } else { __state = __future_base::_S_make_deferred_state(std::__bind_simple( std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); } return future (__state); } /// async, potential overload template inline future ::type> async(_Fn&& __fn, _Args&&... __args) { return async(launch::async|launch::deferred, std::forward<_Fn>(__fn), std::forward<_Args>(__args)...); }
/// Launch code for futures
enum class launch
{
async = 1, //保证异步行为,即传递函数在单独的线程中执行。
deferred = 2 //当其他线程调用get()/waite()访问共享状态时,调用非异步的行为。
};
2、std::future重要成员函数介绍
operator= 移动future对象 share 将*this转移共享状态给shared_future并返回它 get获取返回结果 状态 valid() 检查future是否拥有共享状态 wait() 等待执行结果变成可以获得 wait_for() 等待结果,如果在超过指定时间间隔后仍然无法得到结果,则立即返回3、std::future用法示例
#include#include #include #include #include #include #include using namespace std; class base { public: int baseThread1(int param) { int value = 5; std::cout <<__func__ <<"Reiver param" << param << std::endl; std::cout << __func__ <<"Current Thread ID = "<< std::this_thread::get_id() << std::endl; std::chrono::milliseconds sleep_time(500); std::this_thread::sleep_for(sleep_time); std::cout << "Current Thread ID ="<< std::this_thread::get_id() << std::endl; std::cout << "Return = " << (value + param) << std::endl; return (value + param); } int baseThread2() { int value = 5; std::cout <<__func__ <<"Reiver param"<< std::endl; std::cout << __func__ <<"Current Thread ID = "<< std::this_thread::get_id() << std::endl; std::chrono::milliseconds sleep_time(500); std::this_thread::sleep_for(sleep_time); std::cout << "Current Thread ID ="<< std::this_thread::get_id() << std::endl; std::cout << "Return = " << value<< std::endl; return (value); } }; int main(int agc,char * agv[]) { int temp = 20; base base_test; std::cout << "Main Thread ID = " << std::this_thread::get_id() << std::endl; std::future result = std::async(std::launch::async, &base::baseThread1, &base_test, temp); std::cout << "Continue...." << std::endl; result.wait(); //阻塞在这里,知道result能够获得并得到最后的结果。 //当共享状态值是不可以用时,调用wait接口可以一直阻塞,直到共享状态变为"就绪"时,就变为可以用了。 std::cout << "Final result = " << result.get() << std::endl; return 0; } //OUT //Main Thread ID = 140522049050432 //Continue.... //baseThread1Reiver param20 //baseThread1Current Thread ID = 140522031671040 //Current Thread ID =140522031671040 //Return = 25 //Final result = 25
std::futere查询状态
//查询future的状态
std::future_status status;
do {
status = future.wait_for(std::chrono::seconds(1));
switch(status)
{
case std::future_status::deferred:
std::cout << "std::future_status::deferred" <
4、总结
一般来说std::future都是配合std::async、std::packaged_task和std::promise一起使用。返回其异步执行的结果。使用起来也是非常的银杏。
Todo:
后续补充std::future::wait_for的示例。



