//共享状态的成员
public:
_Ty _Result;
exception_ptr _Exception;
mutex _Mtx;
condition_variable _Cond;
bool _Retrieved;
int _Ready;
bool _Ready_at_thread_exit;
bool _Has_stored_result;
bool _Running;
/*--------------------------------*/
template <class _Fty, class... _ArgTypes>
_NODISCARD future<_Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>> async(
launch _Policy, _Fty&& _Fnarg, _ArgTypes&&... _Args) {
// manages a callable object launched with supplied policy
using _Ret = _Invoke_result_t<decay_t<_Fty>, decay_t<_ArgTypes>...>;
using _Ptype = typename _P_arg_type<_Ret>::type;
_Promise<_Ptype> _Pr(
_Get_associated_state<_Ret>(_Policy, _Fake_no_copy_callable_adapter<_Fty, _ArgTypes...>(
_STD forward<_Fty>(_Fnarg), _STD forward<_ArgTypes>(_Args)...)));
return future<_Ret>(_Pr._Get_state_for_future(), _Nil());
}
template <class _Ty>
class future : public _State_manager<_Ty> {
// class that defines a non-copyable asynchronous return object that holds a value
using _Mybase = _State_manager<_Ty>;
//_State_manager<>内部
_Associated_state<_Ty>* _Assoc_state;//指向共享状态的指针
bool _Get_only_once;
//共享状态是在_Get_associated_state函数内部被new出来的,不同的launch对应不同的_Deferred_async_state或者_Task_async_state它们都是_Packaged_state的子类而_Packaged_state又是共享状态_Associated_state的子类
template <class _Ret, class _Fty>
_Associated_state<typename _P_arg_type<_Ret>::type>* _Get_associated_state(
launch _Psync, _Fty&& _Fnarg) { // construct associated asynchronous state object for the launch type
switch (_Psync) { // select launch type
case launch::deferred:
return new _Deferred_async_state<_Ret>(_STD forward<_Fty>(_Fnarg));
case launch::async: // TRANSITION, fixed in vMajorNext, should create a new thread here
default:
return new _Task_async_state<_Ret>(_STD forward<_Fty>(_Fnarg));
}
}
// CLASS TEMPLATE _Deferred_async_state
template <class _Rx>
class _Deferred_async_state : public _Packaged_state<_Rx()> {
// class for managing associated synchronous state for deferred execution from async
public:
template <class _Fty2>
_Deferred_async_state(const _Fty2& _Fnarg) : _Packaged_state<_Rx()>(_Fnarg) {}//_Deferred_async_state构造函数仅仅只是讲要执行的任务函数保存了起来
template <class _Fty2>
_Deferred_async_state(_Fty2&& _Fnarg) : _Packaged_state<_Rx()>(_STD forward<_Fty2>(_Fnarg)) {}
private:
virtual bool _Has_deferred_function() const noexcept override {
// this function is considered to be deferred until it's invoked
return !this->_Running;
}
virtual void _Run_deferred_function(unique_lock<mutex>& _Lock) override { // run the deferred function//延迟策略中重写了这个虚函数
_Lock.unlock();
_Packaged_state<_Rx()>::_Call_immediate();//依然是_Call_immediate被执行,但是此时是在单线程中执行的,并没有异步创建一个线程执行这个函数
_Lock.lock();
}
};
// CLASS TEMPLATE _Task_async_state
template <class _Rx>
class _Task_async_state : public _Packaged_state<_Rx()> {
// class for managing associated synchronous state for asynchronous execution from async
public:
using _Mybase = _Packaged_state<_Rx()>;
using _State_type = typename _Mybase::_State_type;
template <class _Fty2>
_Task_async_state(_Fty2&& _Fnarg) : _Mybase(_STD forward<_Fty2>(_Fnarg)) {
_Task = ::Concurrency::create_task([this]() { // do it now //注意这里异步策略异步任务线程创建其实在这里create_task;而lambda函数其实就相当于异步任务的入口点
this->_Call_immediate();//这里已经是异步线程调用_Call_immediate了
});
this->_Running = true;
}
virtual ~_Task_async_state() noexcept {
_Wait();
}
virtual void _Wait() override { // wait for completion
_Task.wait();
}
virtual _State_type& _Get_value(bool _Get_only_once) override {
// return the stored result or throw stored exception
_Task.wait();
return _Mybase::_Get_value(_Get_only_once);
}
private:
::Concurrency::task<void> _Task;
};
template <class _Ret, class... _ArgTypes>
class _Packaged_state<_Ret(_ArgTypes...)>
: public _Associated_state<_Ret> { // class for managing associated asynchronous state for packaged_task
public:
using _Mybase = _Associated_state<_Ret>;
using _Mydel = typename _Mybase::_Mydel;
template <class _Fty2>
_Packaged_state(const _Fty2& _Fnarg) : _Fn(_Fnarg) {}
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
template <class _Fty2, class _Alloc>
_Packaged_state(const _Fty2& _Fnarg, const _Alloc& _Al, _Mydel* _Dp)
: _Mybase(_Dp), _Fn(allocator_arg, _Al, _Fnarg) {}
#endif // _HAS_FUNCTION_ALLOCATOR_SUPPORT
template <class _Fty2>
_Packaged_state(_Fty2&& _Fnarg) : _Fn(_STD forward<_Fty2>(_Fnarg)) {}
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
template <class _Fty2, class _Alloc>
_Packaged_state(_Fty2&& _Fnarg, const _Alloc& _Al, _Mydel* _Dp)
: _Mybase(_Dp), _Fn(allocator_arg, _Al, _STD forward<_Fty2>(_Fnarg)) {}
#endif // _HAS_FUNCTION_ALLOCATOR_SUPPORT
void _Call_deferred(_ArgTypes... _Args) { // set deferred call//这个函数其实和下面的_Call_immediate是几乎一模一样的(除了传递的实参)【这个第二实参代表是否在当前线程退出的时候设置共享状态ready并通知】;
//async的延迟策略没有调用过这个函数,都是走的_Call_immediate
_TRY_BEGIN
// call function object and catch exceptions
this->_Set_value(_Fn(_STD forward<_ArgTypes>(_Args)...), true);
_CATCH_ALL
// function object threw exception; record result
this->_Set_exception(_STD current_exception(), true);
_CATCH_END
}
void _Call_immediate(_ArgTypes... _Args) { // call function object
_TRY_BEGIN
// call function object and catch exceptions
this->_Set_value(_Fn(_STD forward<_ArgTypes>(_Args)...), false);//这里执行任务函数成功就设置返回值给共享状态的_Result成员
_CATCH_ALL
// function object threw exception; record result
this->_Set_exception(_STD current_exception(), false);//如果出现异常就提供current_exception函数给共享状态设置_Exception成员
_CATCH_END
}
const function<_Ret(_ArgTypes...)>& _Get_fn() {
return _Fn;
}
private:
function<_Ret(_ArgTypes...)> _Fn;
};
//通过追踪async实现我们发现vs中所谓的共享状态是在async内部 通过_Get_associated_state创建的,async内部构造并返回了future,future内部有一个指针指向共享状态
那么对于延迟策略下的_Deferred_async_state又是什么时候执行任务函数的呢
//_Associated_state
virtual void _Wait() { // wait for signal
unique_lock<mutex> _Lock(_Mtx);
_Maybe_run_deferred_function(_Lock);
while (!_Ready) {
_Cond.wait(_Lock);
}
}
void _Maybe_run_deferred_function(unique_lock<mutex>& _Lock) { // run a deferred function if not already done
if (!_Running) { // run the function
_Running = true;
_Run_deferred_function(_Lock);
}
//
virtual void _Run_deferred_function(unique_lock<mutex>&) {} // do nothing//基类中这是一个virtual函数,而延迟策略对应的_Deferred_async_state对象重写了这个虚函数
总结:对于延迟策略来说,执行任务函数是通过future对象发起get或者wait调用并最终调用其共享状态的_Run_deferred_function虚函数执行的;在内部 _Packaged_state<_Rx()>::_Call_immediate();在单线程中被同步执行;
而对于异步策略来说,是在async内部创建构造共享状态的过程中,即在共享状态的构造函数内部创建一个异步线程执行_Call_immediate的;这里有人会担心异步任务被执行时可能共享状态还没构造完成,这样异步任务的返回值或者异常状态被设置时会不会造成未定义行为;其实不必担心因为根据对象模型在_Task_async_state状态的构造函数内部其基类已经是构造完成的,_Call_immediate主要操作就是调用
任务函数并把返回值写入共享状态,或者发生异常,就把exception_ptr对象写入共享状态对应的成员;这是其共享状态基类成员其实已经是初始化完成的;而共享状态成员对于任务函数来说是隐藏的,即任务
函数内部应该是无法直接读写共享状态的;所以对共享状态的读写操作由_Call_immediate函数完成;这样就保证了安全!
基于virtual studio编译器的C++标准高级接口async实现 分析future与共享状态以及异步任务的关系
于 2022-06-14 16:36:23 首次发布