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...
}
涉及文件
待实现函数
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 # 运行
Last updated