协程
英文: Coroutines.
标准: C++20.
并发性与并行性
- 并发性: 拥有处理多任务的能力, 不一定是同时进行.
- 并行性: 拥有同时处理多任务的能力, 不是间隔执行.
协程与线程
- 一般情况下, 一个进程可以开启几十亿个协程, 而只能开启不超过 2048 个线程.
- 协程是协作式多任务的, 而线程典型是抢占式多任务的.
- 协程是语言层级的构造, 而线程是系统层级的构造. 因此协程的调度与内核无关, 而线程由内核调度.
- 协程的切换比较快速, 而线程的切换需要内核进行调度.
- 协程可以在单个线程中执行多个任务, 而线程可以充分利用多核 CPU 的运算力, 以及降低堵塞操作对性能的影响.
因为协程的调度与内核无关, 所以当某个线程的某个协程调用的堵塞的操作将导致线程挂起, 所有属于该线程的协程也会挂起. 因此要进一步利用协程提高效率需要结合异步操作.
C++20 加入了对无栈协程的支持, 但只提供了最基础的接口. 直接使用过于繁琐, 应先进行封装. 可以参考:
- Boost.ASIO: 包含无栈协程.
- Boost.Coroutine: 对称/非对称的有栈协程, API 风格比较老式.
- Boost.Coroutine2: 非对称的有栈协程, API 风格现代.
- Boost.Fiber: 带有调度器的有栈协程, 调度导致效率较低.
关键字
- co_yield: 暂停执行并返回一个值.
- co_await: 暂停执行.
- co_return: 完成执行并返回一个值.