tinyCoroLab Docs
直通tinyCoroLab源码直通tinyCoro源码
latest
latest
  • 🚀开启你的tinyCoroLab之旅!
  • 📮致读者
  • 👊C++协程入门
    • 协程初探
    • 有栈协程VS无栈协程
    • C++协程入门实践
    • 从编译器视角揭秘 C++ 协程
    • 协程调用优化
  • 🌟认识io_uring
  • 📖tinyCoroLab实验介绍
  • 📘Lab1 构建协程任务封装
    • Lab1 构建协程任务封装
    • Lab1 实验解析
  • 📗Lab2 构建任务执行引擎
    • Lab2a 构建任务执行引擎engine
    • Lab2a 实验解析
    • Lab2b 构建任务执行引擎context
    • Lab2b 实验解析
  • 📙Lab3 封装异步I/O执行模块
  • 📕Lab4 构建基础协程同步组件
    • Lab4pre 如何构建协程同步组件
    • Lab4a 构建基础协程同步组件event
    • Lab4a 实验解析
    • Lab4b 构建基础协程同步组件latch
    • Lab4b 实验解析
    • Lab4c 构建基础协程同步组件wait_group
    • Lab4c 实验解析
    • Lab4d 构建基础协程同步组件mutex
    • Lab4d 实验解析
  • 📓Lab5 构建进阶协程同步组件
    • Lab5a(选做) 构建进阶协程同步组件when_all
    • Lab5a 实验解析
    • Lab5b 构建进阶协程同步组件condition_variable
    • Lab5b 实验解析
    • Lab5c 构建进阶协程同步组件channel
    • Lab5c 实验解析
  • ✨tinyCoro Bonus Lab
  • 🎯tinyCoro悬赏令
  • ⚔️面试实战
    • 面试实战
    • tinyCoro面试相关问题
  • 🚩实验总结-终点亦是起点
  • 🪐番外杂谈
    • 从编译器视角揭秘 C++ 协程
    • 协程调用优化
  • 📌更新日志
Powered by GitBook
On this page
  • tinyCoroLab4b 实验简介
  • 📖lab4b 任务书
  • 实验前置讲解
  • ⚠️注意事项
  • 实验任务书
  • 🔖测试
  1. 📕Lab4 构建基础协程同步组件

Lab4b 构建基础协程同步组件latch

tinyCoroLab4b 实验简介

本节我们将正式开始 tinyCoroLab4b,即构建基础协程同步组件 latch。如果实验者对 event 进行了正确的实现,那么 latch 的构建将会十分轻松。

预备知识

⚠️预备知识即在实验开始前你应该已经掌握的知识,且在知识铺垫章节中均有涉及

  • C++ 协程 awaiter 的概念

  • C++ 模板编程

📖lab4b 任务书

实验前置讲解

本节实验涉及到的核心文件为include/coro/comp/latch.hpp和src/comp/latch.cpp,实验者需要预先打开文件浏览大致代码结构,下面针对该文件内容进行讲解。

与 lab4a 情况类似,include/coro/comp/latch.hpp中给出了一个非常简单的 latch 的定义,注意该定义仅仅是一个形式,不具备 latch 的正确功能,但是其类以及函数声明形式是正确的。

另外该文件预定义了latch_guard,在其生命周期结束后可以自动对 latch 调用count_down,实验者不要修改任何关于 guard 的定义。

⚠️注意事项

  • 请确保已阅读过tinyCoroLab Introduce章节。

  • 为了确保正确实现目标函数,实验者可能需要做一些额外操作:新增类、修改现有类的实现、补充现有类的方法和成员变量等操作,请遵循free-design 实验原则。

  • 你需要仔细评估待实现的接口是否需要是线程安全的。

  • 任何导致测试卡住、崩溃等无法使测试顺利通过的情况都表明你的代码存在问题。

实验任务书

🧑‍💻Task #1 - 实现 latch

任务目标

tinyCoro 的 latch 组件与 C++ 的 std::latch 功能是一样的,构造函数包含一个整数类型指明 latch 初始的计数,对用户提供下列两个接口:

auto count_down() noexcept -> void; // 普通调用
auto wait() noexcept -> awaiter; // 协程调用,awaiter 的 await_resume 返回 void

wait_func调用co_await latch.wait()时,如果 latch 的计数大于 0,那么陷入 suspend 状态,并将 suspend awaiter 挂载到 latch 里。

count_down_func调用latch.count_down()来使得计数减 1,如果此时计数降至 0,那么应该 resume 所有的 suspend awaiter。

实验者不拿发现 latch 完全可以靠 event 来实现对协程的挂载以及恢复,而自身只需要维护计数就可以了。

下面给出 latch 的使用场景便于实验者理解:

latch lt(1);
task<> countdown_func() { // 手动调用 count_down
  // codes...
  lt.count_down();
}
task<> countdown_func() { // 自动调用 count_down
  auto guard = latch_guard(lt);
  // codes...
  // auto count_down
}
task<> wait_func() {
  co_await lt.wait();
  // codes...
}

涉及文件

  • include/coro/comp/latch.hpp

  • src/comp/latch.cpp

待实现函数

  • coro::latch::count_down

  • coro::latch::wait

补充说明

  • 你的实现必须包含任务目标中描述的函数且函数声明形式必须一致,不然无法正常编译

  • 协程函数的返回类型可以被修改,但必须是 awaiter 或者 awaitable 类型且 await_resume 返回类型与任务书规定一致

  • 请务必考虑多线程安全性问题

  • 因为 tinyCoro 设计问题,所以协程组件恢复 suspend awaiter 时最好将其派发到其原本运行的 context

🔖测试

功能测试

功能测试场景主要针对:

  • 单个 context 下 latcth 的 count_down 与 wait

  • 多个 context 下 latcth 的 count_down 与 wait

完成本节实验后,实验者请在构建目录下执行下列指令来构建以及运行测试程序:

make build-lab4b # 构建
make test-lab4b # 运行

内存安全测试

在构建目录下运行下列指令来执行内存安全测试:

make memtest-lab4b

测试通过会提示 pass,不通过会给出 valgrind 的输出文件位置,请实验者根据该文件排查内存故障。

性能测试

💡tinyCoroLab预置了用于性能调优的火焰图生成脚本哦!详情请查看scripts/README.MD。

在tinyCoroLab Introduce章节中提到性能测试的三种模型:

  • thread_pool_stl_XX: 使用简单的线程池和 stl 组件。

  • coro_stl_XX: 使用 coro 调度器和 stl 组件。

  • coro_XX: 使用 coro 调度器和 coro 组件。

对于 lab4b 的性能测试,coro 组件即实验者实现的 latch,stl 组件即 C++ std::latch,测试场景为多个函数 count_down 和多个函数 wait,并测量执行总耗时。

实验者只要重点关注coro_stl_XX和coro_XX模型输出的结果差异即可,该结果反映的实验者的实现与 stl 实现的性能差异。由于线程在受线程同步组件影响而陷入阻塞态时并不会选择执行其他任务,但 tinyCoro 执行引擎会,因此为了保证公平性,每个线程只会被派发一个任务,性能测试也仅仅是想重点关注实验者的实现与 stl 实现的性能差异。

在构建目录下运行下列指令来构建和运行性能测试:

make benchbuild-lab4b # 构建
make benchtest-lab4b # 运行
PreviousLab4a 实验解析NextLab4b 实验解析

Last updated 1 month ago