赞
踩
类模板 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 <future>
std::future作用是希望线程返回一个结果,用于异步的操作。
下面,首先看下std::__basic_future 的定义:
/// Common implementation for future and shared_future. template<typename _Res> class __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<bool>(_M_state); } void wait() const { _State_base::_S_check(_M_state); _M_state->wait(); } template<typename _Rep, typename _Period> future_status wait_for(const chrono::duration<_Rep, _Period>& __rel) const { _State_base::_S_check(_M_state); return _M_state->wait_for(__rel); } template<typename _Clock, typename _Duration> 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. template<typename _Res> class future : public __basic_future<_Res> { friend class promise<_Res>; template<typename> friend class packaged_task; template<typename _Fn, typename... _Args> friend future<typename result_of<_Fn(_Args...)>::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<R&> template<typename _Res> class future<_Res&> : public __basic_future<_Res&> { friend class promise<_Res&>; template<typename> friend class packaged_task; template<typename _Fn, typename... _Args> friend future<typename result_of<_Fn(_Args...)>::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<void> template<> class future<void> : public __basic_future<void> { friend class promise<void>; template<typename> friend class packaged_task; template<typename _Fn, typename... _Args> friend future<typename result_of<_Fn(_Args...)>::type> async(launch, _Fn&&, _Args&&...); typedef __basic_future<void> _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<void> 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 template<typename _Fn, typename... _Args> future<typename result_of<_Fn(_Args...)>::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<result_type>(__state); } /// async, potential overload template<typename _Fn, typename... _Args> inline future<typename result_of<_Fn(_Args...)>::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()访问共享状态时,调用非异步的行为。
};
operator= 移动future对象
share 将*this转移共享状态给shared_future并返回它
get获取返回结果
状态
valid() 检查future是否拥有共享状态
wait() 等待执行结果变成可以获得
wait_for() 等待结果,如果在超过指定时间间隔后仍然无法得到结果,则立即返回
/************************************************************************* > File Name: thread_future.cpp > Author: 小和尚敲木鱼 > Mail: > Created Time: Tue 21 Sep 2021 02:13:25 AM PDT ************************************************************************/ #include <iostream> #include <thread> #include <string> #include <vector> #include <mutex> #include <future> #include <chrono> 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<int> 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" <<std::endl; break; case std::future_status::timeout: std::cout << "std::future_status::timeout" <<std::endl; break; case std::future_status::ready: std::cout << "std::future_status::ready" <<std::endl; break; default: std::cout << "none status" << std::endl; break; } } while (status != std::future_status::ready);
一般来说std::future都是配合std::async、std::packaged_task和std::promise一起使用。返回其异步执行的结果。使用起来也是非常的银杏。
Todo:
后续补充std::future::wait_for的示例。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。