std::packaged_task 源码分析

背景:

c++ 线程池,需要对任务进行包装, packaged_task是不二之选,接下来就分析下源码具体内容

std::packaged_task 源码

C++
template<class _Rp, class ..._ArgTypes>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
{
public:
    typedef _Rp result_type; // extension
    //struct __uncvref  {
  //  typedef _LIBCPP_NODEBUG_TYPE typename remove_cv<typename remove_reference<_Tp>::type>::type type;
    //};
template <class _Fp,
          class = typename enable_if
          <
              !is_same<
                  typename __uncvref<_Fp>::type,
                  packaged_task
                  >::value
              >::type
         >
    _LIBCPP_INLINE_VISIBILITY
    explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
    
private:
    __packaged_task_function<result_type(_ArgTypes...)> __f_;
    promise<result_type>                                __p_;
    
 }

也就说packaged_task 的指针里边有两个__f_, __p_成员,promise我在之前文档已经分析了源码了,这里就不多赘述,接下来对__f_ 这个成员做分析,也就是__packaged_task_function<result_type(_ArgTypes...)>

__packaged_task_function 

C++
template<class _Rp, class ..._ArgTypes>
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
{
    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
    typename aligned_storage<3*sizeof(void*)>::type __buf_;
    __base* __f_;

public:
    typedef _Rp result_type;

// construct/copy/destroy:
    _LIBCPP_INLINE_VISIBILITY
    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
    template<class _Fp>
      __packaged_task_function(_Fp&& __f);
    template<class _Fp, class _Alloc>
      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);

__packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;

__packaged_task_function(const __packaged_task_function&) =  delete;
    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;

~__packaged_task_function();

void swap(__packaged_task_function&) _NOEXCEPT;

_LIBCPP_INLINE_VISIBILITY
    _Rp operator()(_ArgTypes...) const;
};

__packaged_task_function 主要是记录了packaged_task 的可调用对象,或者函数指针之类的,接下来看下它的构造方法的实现

__packaged_task_function 构造方法

C++
template<class _Rp, class ..._ArgTypes>
template <class _Fp>
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
    : __f_(nullptr)
{
    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
    if (sizeof(_FF) <= sizeof(__buf_))
    {
        __f_ = (__base*)&__buf_;
        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
    }
    else
    {
        typedef allocator<_FF> _Ap;
        _Ap __a;
        typedef __allocator_destructor<_Ap> _Dp;
        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
        __f_ = __hold.release();
    }
}

可以看的出来如果是函数指针会走上边的if分支,这里__f_ = (__base*)&__buf_;
        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f)); 完成了函数指针记录到这个packaged_task里边

packaged_task 的构造方法只是记录了调用可调用的对象,后边真正调用的会在operate (),那就看下重写() 实现,就可以知道其原理

packaged_task<_Rp(_ArgTypes...)>::operator()

C++
 template<class _Rp, class ..._ArgTypes>
void
packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
{
   ndef _LIBCPP_NO_EXCEPTIONS
    try
    {
#endif  // _LIBCPP_NO_EXCEPTIONS
        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
#ifndef _LIBCPP_NO_EXCEPTIONS
    }
    catch (...)
    {
        __p_.set_exception(current_exception());
    }
#endif  // _LIBCPP_NO_EXCEPTIONS
}

很容易就可以看出来__p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); __p_ 记录了__f_调用结果,这就好理解了

std::packaged_task 源码分析相关推荐

  1. STL std::sort 源码分析

    转载自http://feihu.me/blog/2014/sgi-std-sort/ 最近在看sort源码,看到这篇博文很好,转发作为记录,转载侵权联系我删除 背景 在校期间,为了掌握这些排序算法,我 ...

  2. “vector”: 不是“std”的成员_libcxx 的 std::function 源码分析

    链接:functional.其中 std::function 的主体内容在 2100 多行. 先来看 function 的头部. template<class _Rp, class ..._Ar ...

  3. is not a function_libcxx 的 std::function 源码分析

    链接:functional.其中 std::function 的主体内容在 2100 多行. 先来看 function 的头部. template 其中的 libcpp template vis 宏是 ...

  4. std::move()源码分析

    https://segmentfault.com/a/1190000020744971?utm_source=tag-newest C++11 引入右值和移动语义,其中std::move()是不可或缺 ...

  5. ceph bluestore 源码分析:刷缓存(trim)逻辑

    环境 ceph版本:12.2.1 部署模式:ec 2+1 osd: 3个 且资源池已经有数据 执行命令:ceph daemon osd.0 flush_store_cache 进行刷缓存.即将dump ...

  6. ceph bluestore 源码分析:ceph-osd内存查看方式及控制源码分析

    文章目录 内存查看 内存控制 内存控制源码分析 通过gperftools接口获取osd进程实际内存 动态设置cache大小 动态调整cache比例 trim释放内存 本文通过对ceph-osd内存查看 ...

  7. Google Mock(Gmock)简单使用和源码分析——源码分析

    源码分析 通过<Google Mock(Gmock)简单使用和源码分析--简单使用>中的例子,我们发现被mock的相关方法在mock类中已经被重新实现了,否则它们也不会按照我们的期待的行为 ...

  8. EOS智能合约:system系统合约源码分析

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. eosio.system 概览 笔者使用的IDE是VScode,首先来看eosio.system的源码结构.如下图所示. ...

  9. 以太坊C++客户端Aleth源码分析,转账交易和智能合约的入口代码

    本文主要记录以太坊C++客户端Aleth的源码分析和相关实验过程和结果.本文将讲解两部分的内容,一是转账交易和智能合约的入口代码在哪里?二是通过实验验证转账交易和智能合约交易这两种不同交易所对应的不同 ...

最新文章

  1. Mybatis结果集映射
  2. python元组的定义方式_学习Python元组,有哪些必须要掌握的内容
  3. 第4章 旋转蛇(《C和C++游戏趣味编程》配套教学视频)
  4. oracle函数listagg的使用说明(分组后连接字段)
  5. 消息中间件MQ与RabbitMQ面试题
  6. 手机上将mp4转换成amv_如何在Linux上将tiff图像从RGB颜色转换为CMYK颜色?
  7. type-c边玩边充电游戏手柄方案
  8. ubantu + anaconda + TensorFlow 1.13.1
  9. anaconda安装dlib出现ImportError: libopenblas.so.0: cannot open shared object file***
  10. 电脑 耳机播放声音,左右耳朵不平衡解决方法
  11. END-TO-END DNN BASED SPEAKER RECOGNITION INSPIRED BY I-VECTOR AND PLDA
  12. Registration
  13. 程序猿专用代码注释:佛祖保佑,永无BUG
  14. 终极三国 片头曲-对手歌词 片尾曲-够爱歌词
  15. 尼日利亚SONCAP免验货办理
  16. Django配置Bootstrap, js
  17. Codeforces 584E. Anton and Ira (排列好题)
  18. vert.x oracle 数据库,深入浅出Vert.x架构
  19. DS007-队列的原理-操作受限的线性表-queue的使用
  20. 玩转 Windows Terminal

热门文章

  1. Seata Failed to get available servers: endpoint format should like ip:port 报错原因/解决方案汇总版(看完本文必解决问题)
  2. Disconnected: No supported authentication methods available(server sent: publickey) 的解决办法
  3. Nachos project1 领悟
  4. vue中a标签的href属性的写法
  5. ug998逻辑思维导图
  6. 做一个广告业务后台需要几天,5天吗?不,用PhalApi开源框架,1天就能做好
  7. JAVA设计模式第三讲:结构型设计模式
  8. 录音m4a怎么转换成mp3
  9. 计算机设计辅助 CAD 试题汇编,计算机辅助设计试题汇编-第二单元
  10. matlab生成gif动图