写点什么

一个 cpp 协程库的前世今生(六)管理器 manager

作者:SkyFire
  • 2022 年 1 月 01 日
  • 本文字数:2490 字

    阅读完需:约 8 分钟

一个cpp协程库的前世今生(六)管理器manager

为了防止大家找不到代码,还是先贴一下项目链接:


GitHub - skyfireitdiy/cocpp at cocpp-0.1.0


前面介绍了 ctx 和 env,本文介绍三个基础组件最后一个:管理器 manager。


管理器的职责是管理运行环境和协程的生命周期、各种资源的控制,以及协程运行情况的监控。其主要数据结构定义在 include/core/co_manager.h 中。


    co_env_set env_set__ {        .normal_env_count = 0,                                      // 正常环境数量        .base_env_count   = std::thread::hardware_concurrency(),    // 基础环境数量        .max_env_count    = std::thread::hardware_concurrency() * 2 // 最大环境数量    };                                                              // 协程调度环境集合
co_factory_set factory_set__ { .env_factory = co_env_factory::instance(), // 环境工厂 .ctx_factory = co_ctx_factory::instance(), // 协程工厂 .stack_factory = co_stack_factory::instance() // 堆栈工厂 }; // 工厂集合
bool clean_up__ { false }; // 是否需要清理协程调度环境 co_spinlock clean_up_lock__ { co_spinlock::lock_type::in_thread }; // 清理协程调度环境锁 std::list<std::future<void>> background_task__; // 后台任务队列 mutable co_spinlock mu_timer_duration__ { co_spinlock::lock_type::in_thread }; // 定时器时间锁 std::chrono::high_resolution_clock::duration timer_duration__ { std::chrono::milliseconds(10) }; // 定时器时间 size_t default_shared_stack_size__ = CO_DEFAULT_STACK_SIZE; // 默认共享堆栈大小 std::function<bool()> need_free_mem_cb__ { [] { return false; } }; // 需要释放内存回调 co_spinlock need_free_mem_cb_lock__ { co_spinlock::lock_type::in_thread }; // 需要释放内存回调锁
复制代码


接下来逐一介绍以上成员。

环境集合 env_set__

环境集合管理当前的所有环境。其结构定义在 include/core/type.h 中:


struct co_env_set{    std::unordered_set<co_env*> normal_set;                                                // 普通线程环境    std::recursive_mutex        normal_lock;                                               // 普通线程环境互斥锁    std::unordered_set<co_env*> expired_set;                                               // 过期线程环境    std::recursive_mutex        expired_lock;                                              // 过期线程环境互斥锁    std::condition_variable_any cond_expired_env;                                          // 过期线程环境条件变量    unsigned int                normal_env_count;                                          // 普通线程环境数量    co_spinlock                 mu_normal_env_count { co_spinlock::lock_type::in_thread }; // 普通线程环境数量互斥锁    unsigned int                base_env_count;                                            // 基础线程环境数量    unsigned int                max_env_count;                                             // 最大线程环境数量};
复制代码


  • normal_set 表示正常状态的运行环境集合,normal_lock 是保护该集合的锁。

  • expired_set 表示将要被销毁的环境集合,expired_lock 是该集合的锁。

  • cond_expired_env 是销毁过期环境使用的条件变量,被清理线程使用。(清理线程在后文会讲到)

  • normal_env_count 表示正常状态运行环境的数量,mu_normal_env_count 是保护该变量的锁。

  • base_env_count 表示基础环境数量,当当前的环境数量小于 base_env_count 时,每创建一个新的协程都会创建一个新的运行环境去执行。

  • max_env_count 表示最大的环境数量,当现有环境数量超过这个阈值之后,管理器就会销毁一部分执行环境,保持同时存在的执行环境在此范围之内。

工厂集合 factory_set__

工厂集合中有三个工厂:


  • 执行环境工厂 env_factory 负责创建和销毁执行环境。

  • 上下文工厂 ctx_factory 负责创建和销毁协程上下文。

  • 栈工厂 stack_factory 负责创建和销毁运行时栈。


这些工厂的底层都有内存池和对象池支撑,详情将在后面内存相关章节中叙述。

清理标记 clean_up__及其保护锁 clean_up_lock__

clean_up__标记控制一些后台任务的退出。

后台任务集合 background_task__

运行于后台的任务集合,主要包括:


  • 协程运行环境清理任务,负责清理由于超出最大环境数量而需要销毁的执行环境,以及最后的应用程序退出时销毁所有的执行环境。

  • 定时器线程,负责执行定时任务。定时任务包括:强制调度、协程迁移、协程偷取、标记多余环境、内存池及对象池内存释放。这些实现在后面的章节会介绍。

定时器超时时长 timer_duration__ 及其保护锁 mu_timer_duration__

timer_duration__ 用于为定时器线程设置超时时间。

默认共享栈大小 default_shared_stack_size__

在管理器创建执行环境的时候,会为执行环境创建一个默认的共享栈,其大小由 default_shared_stack_size__ 指定,默认为 8MB,在 include/core/co_define.h 文件中定义。

内存释放回调函数 need_free_mem_cb__ 及其保护锁 mu_need_free_mem_cb__

在定时任务中,会定期调用此函数来判断是否需要进行内存释放,当此函数返回 true 时,会尝试释放工厂中的内存池以及对象池的资源。此回调函数默认会返回 false,也就是不释放。

总结

本文介绍了 cocpp 框架三大基础组件中的最后一部分,希望读者朋友可以对整体架构有个认识,方便后面文章的理解。

发布于: 46 分钟前
用户头像

SkyFire

关注

这个cpper很懒,什么都没留下 2018.10.13 加入

会一点点cpp的苦逼码农

评论

发布
暂无评论
一个cpp协程库的前世今生(六)管理器manager