栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

基于virtual studio编译器的C++标准高级接口async实现 分析future与共享状态以及异步任务的关系

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于virtual studio编译器的C++标准高级接口async实现 分析future与共享状态以及异步任务的关系

//共享状态的成员
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 
_NODISCARD future<_Invoke_result_t, 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<_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 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 
_Associated_state::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 _Deferred_async_state : public _Packaged_state<_Rx()> {
    // class for managing associated synchronous state for deferred execution from  async
public:
    template 
    _Deferred_async_state(const _Fty2& _Fnarg) : _Packaged_state<_Rx()>(_Fnarg) {}//_Deferred_async_state构造函数仅仅只是讲要执行的任务函数保存了起来
    template 
    _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& _Lock) override { //  run the deferred function//延迟策略中重写了这个虚函数
        _Lock.unlock();
        _Packaged_state<_Rx()>::_Call_immediate();//依然是_Call_immediate被执行,但是此时是在单线程中执行的,并没有异步创建一个线程执行这个函数
        _Lock.lock();
    }
};

// CLASS TEMPLATE _Task_async_state
template 
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 
    _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 _Task;
};
template 
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 
    _Packaged_state(const _Fty2& _Fnarg) : _Fn(_Fnarg) {}
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
    template 
    _Packaged_state(const _Fty2& _Fnarg, const _Alloc& _Al, _Mydel* _Dp)
        : _Mybase(_Dp), _Fn(allocator_arg, _Al, _Fnarg) {}
#endif // _HAS_FUNCTION_ALLOCATOR_SUPPORT
    template 
    _Packaged_state(_Fty2&& _Fnarg) : _Fn(_STD forward<_Fty2>(_Fnarg)) {}
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
    template 
    _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是一模一样的;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 _Lock(_Mtx);
        _Maybe_run_deferred_function(_Lock);
        while (!_Ready) {
            _Cond.wait(_Lock);
        }
    }
void _Maybe_run_deferred_function(unique_lock& _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&) {} // 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函数完成;这样就保证了安全!













转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/971288.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号