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

std::async 源码解析

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

std::async 源码解析

本次采用的xcode std++11 对应的源码分析


async对应的源码
template 
future::type, typename decay<_Args>::type...>::type>
async(_Fp&& __f, _Args&&... __args)
{
    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
                                    _VSTD::forward<_Args>(__args)...);
}

template 

future::type, typename decay<_Args>::type...>::type>
async(launch __policy, _Fp&& __f, _Args&&... __args)
{
    typedef __async_func::type, typename decay<_Args>::type...> _BF;
    typedef typename _BF::_Rp _Rp;

#ifndef _LIBCPP_NO_EXCEPTIONS
    try
    {
#endif
        if (__does_policy_contain(__policy, launch::async))
        return _VSTD::__make_async_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
                                                     _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
#ifndef _LIBCPP_NO_EXCEPTIONS
    }
    catch ( ... ) { if (__policy == launch::async) throw ; }
#endif

        return future<_Rp>{};
}


先讨论这个,异步执行的__make_async_assoc_state

C++
template
_LIBCPP_INLINE_VISIBILITY future<_Rp>
__make_async_assoc_state(_Fp&& __f)
{
    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
    return future<_Rp>(__h.get());
}

也就是说这个接口返回了future对象,并把__async_assoc_state 指针作为future对象的构造方法传递进去了

__async_assoc_state

  这个类对象继承了__assoc_state<_Rp>

重点关注下__on_zero_shared() 这个方法

C++
template
class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
    : public __assoc_state<_Rp>
{
    typedef __assoc_state<_Rp> base;

    _Fp __func_;

    virtual void __on_zero_shared() _NOEXCEPT;
public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __async_assoc_state(_Fp&& __f);

    virtual void __execute();
};
 

 子类__assoc_state

C++
template
class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
    : public __assoc_sub_state
{
    typedef __assoc_sub_state base;
    typedef typename aligned_storage::value>::type _Up;
protected:
    _Up __value_;

    virtual void __on_zero_shared() _NOEXCEPT;
public:

    template
    void set_value(_Arg&& __arg);

    template
    void set_value_at_thread_exit(_Arg&& __arg);

    _Rp move();
    typename add_lvalue_reference<_Rp>::type copy();
};

子类__assoc_sub_state

C++
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
    : public __shared_count
{
protected:
    exception_ptr __exception_;
    mutable mutex __mut_;
    mutable condition_variable __cv_;
    unsigned __state_;

    virtual void __on_zero_shared() _NOEXCEPT;
    void __sub_wait(unique_lock& __lk);
public:
    enum
    {
        __constructed = 1,
        __future_attached = 2,
        ready = 4,
        deferred = 8
    };

    _LIBCPP_INLINE_VISIBILITY
    __assoc_sub_state() : __state_(0) {}

    _LIBCPP_INLINE_VISIBILITY
    bool __has_value() const
        {return (__state_ & __constructed) || (__exception_ != nullptr);}

    _LIBCPP_INLINE_VISIBILITY
    void __attach_future() {
        lock_guard __lk(__mut_);
        bool __has_future_attached = (__state_ & __future_attached) != 0;
        if (__has_future_attached)
            __throw_future_error(future_errc::future_already_retrieved);
        this->__add_shared();
        __state_ |= __future_attached;
    }

    _LIBCPP_INLINE_VISIBILITY
    void __set_deferred() {__state_ |= deferred;}

    void __make_ready();
    _LIBCPP_INLINE_VISIBILITY
    bool __is_ready() const {return (__state_ & ready) != 0;}

    void set_value();
    void set_value_at_thread_exit();

    void set_exception(exception_ptr __p);
    void set_exception_at_thread_exit(exception_ptr __p);

    void copy();

    void wait();
    template
        future_status
        _LIBCPP_INLINE_VISIBILITY
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
    template
        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
        future_status
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;

    virtual void __execute();
};

子类__shared_count

C++
class _LIBCPP_TYPE_VIS __shared_count
{
    __shared_count(const __shared_count&);
    __shared_count& operator=(const __shared_count&);

protected:
    long __shared_owners_;
    virtual ~__shared_count();
private:
    virtual void __on_zero_shared() _NOEXCEPT = 0;

public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __shared_count(long __refs = 0) _NOEXCEPT
        : __shared_owners_(__refs) {}

#if defined(_LIBCPP_BUILDING_LIBRARY) &&
    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
    void __add_shared() _NOEXCEPT;
    bool __release_shared() _NOEXCEPT;
#else
    _LIBCPP_INLINE_VISIBILITY
    void __add_shared() _NOEXCEPT {
      __libcpp_atomic_refcount_increment(__shared_owners_);
    }
    _LIBCPP_INLINE_VISIBILITY
    bool __release_shared() _NOEXCEPT {
      if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
        __on_zero_shared();
        return true;
      }
      return false;
    }
#endif
    _LIBCPP_INLINE_VISIBILITY
    long use_count() const _NOEXCEPT {
        return __libcpp_relaxed_load(&__shared_owners_) + 1;
    }
};

为什么async 执行后 async返回对象销毁时候,必须等待异步任务执行完成呢?

std::future

C++
template
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
{
    __assoc_state<_Rp>* __state_;

    explicit future(__assoc_state<_Rp>* __state);

    template friend class promise;
    template friend class shared_future;

    template
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
    template
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);

public:
    _LIBCPP_INLINE_VISIBILITY
    future() _NOEXCEPT : __state_(nullptr) {}
    _LIBCPP_INLINE_VISIBILITY
    future(future&& __rhs) _NOEXCEPT
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
    future(const future&) = delete;
    future& operator=(const future&) = delete;
    _LIBCPP_INLINE_VISIBILITY
    future& operator=(future&& __rhs) _NOEXCEPT
        {
            future(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }

    ~future();
    _LIBCPP_INLINE_VISIBILITY
    shared_future<_Rp> share() _NOEXCEPT;

    // retrieving the value
    _Rp get();

    _LIBCPP_INLINE_VISIBILITY
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}

    // functions to check state
    _LIBCPP_INLINE_VISIBILITY
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}

    _LIBCPP_INLINE_VISIBILITY
    void wait() const {__state_->wait();}
    template
        _LIBCPP_INLINE_VISIBILITY
        future_status
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
            {return __state_->wait_for(__rel_time);}
    template
        _LIBCPP_INLINE_VISIBILITY
        future_status
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
            {return __state_->wait_until(__abs_time);}
};

这里重点关注下~future() 的西沟方法

C++
template
future<_Rp>::~future()
{
    if (__state_)
        __state_->__release_shared();
}

__shared_count::__release_shared

C++
 template class _LIBCPP_TEMPLATE_VIS weak_ptr;

class _LIBCPP_TYPE_VIS __shared_count
{
 bool __release_shared() _NOEXCEPT {
      if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
        __on_zero_shared();
        return true;
      }
      return false;
    }
 }

__async_assoc_state::__on_zero_shared

C++
template
void
__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
{
    this->wait();
    base::__on_zero_shared();
}

C++
void
__assoc_sub_state::wait()
{
    unique_lock __lk(__mut_);
    __sub_wait(__lk);
}
 

C++

void
__assoc_sub_state::__sub_wait(unique_lock& __lk)
{
    if (!__is_ready())
    {
        if (__state_ & static_cast(deferred))
        {
            __state_ &= ~static_cast(deferred);
            __lk.unlock();
            __execute();
        }
        else
            while (!__is_ready())
                __cv_.wait(__lk);
    }
}

也就是说在async 返回的future在西沟方法中最终会调用wait方法,这也就是解释了味了退出的时候会调用wait方法

Async defer模式

__make_deferred_assoc_state

C++
template

future::type, typename decay<_Args>::type...>::type>
async(launch __policy, _Fp&& __f, _Args&&... __args)
{
    typedef __async_func::type, typename decay<_Args>::type...> _BF;
    typedef typename _BF::_Rp _Rp;

    if (__does_policy_contain(__policy, launch::deferred))
        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
                                                        _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
    return future<_Rp>{};
}
template
_LIBCPP_INLINE_VISIBILITY future<_Rp>
__make_deferred_assoc_state(_Fp&& __f)
{
    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
    return future<_Rp>(__h.get());
}

 

可以看的出来 它跟async模式不一样,没有直接创建一个thread

__deferred_assoc_state

C++
template
class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
    : public __assoc_state<_Rp>
{
    typedef __assoc_state<_Rp> base;

    _Fp __func_;

public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __deferred_assoc_state(_Fp&& __f);

    virtual void __execute();
};

__deferred_assoc_state<_Rp, _Fp>::__execute()

C++
template
void
__deferred_assoc_state<_Rp, _Fp>::__execute()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    try
    {
#endif // _LIBCPP_NO_EXCEPTIONS
        this->set_value(__func_());
#ifndef _LIBCPP_NO_EXCEPTIONS
    }
    catch (...)
    {
        this->set_exception(current_exception());
    }
#endif // _LIBCPP_NO_EXCEPTIONS
}

__execute() 什么时候执行的

 调用wait方法的时候

C++
void
__assoc_sub_state::wait()
{
    unique_lock __lk(__mut_);
    __sub_wait(__lk);
}
 

C++

void
__assoc_sub_state::__sub_wait(unique_lock& __lk)
{
    if (!__is_ready())
    {
        if (__state_ & static_cast(deferred))
        {
            __state_ &= ~static_cast(deferred);
            __lk.unlock();
            __execute();
        }
        else
            while (!__is_ready())
                __cv_.wait(__lk);
    }
}

 

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

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

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