0% found this document useful (0 votes)
53 views14 pages

1 - Coroutines 基本概念与极简模型

The document discusses C++ coroutines including their basic concepts, reference materials, standards, support libraries, and examples. Coroutines provide an alternative to threads for asynchronous programming by allowing suspension and resumption of functions using compiler-supported stack switching. They can improve performance, concurrency, and usability compared to threads.

Uploaded by

张奎
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
53 views14 pages

1 - Coroutines 基本概念与极简模型

The document discusses C++ coroutines including their basic concepts, reference materials, standards, support libraries, and examples. Coroutines provide an alternative to threads for asynchronous programming by allowing suspension and resumption of functions using compiler-supported stack switching. They can improve performance, concurrency, and usability compared to threads.

Uploaded by

张奎
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

Coroutines 基本概念与极简模型​

官方Coroutines 资料​
Coroutines 参考 ​
https://en.cppreference.com/w/cpp/language/coroutines ​
Coroutines 标准 ​
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4775.pdf ​
Coroutines 支持库 ​
https://github.com/lewissbaker/cppcoro ​

• task<T> ​
• shared_task<T> ​
• generator<T> ​
• async_generator<T> ​
• async_mutex<T> ​
Coroutines Hello world ​
https://blog.panicsoftware.com/your-first-coroutine/ ​
Coroutines 是什么​
使用者角度​
1. 同步方式​

2. 异步方式1​

3. 异步方式2​
4. boost::future

5. coroutines​
6. 代码实例​

抽象概念​
• 一种编译器支持的对 set_jump(...) long_jump(...)的安全封装, 实现线程栈间安全跳转​
• 堆上的栈
• 对boost::coroutines boost::coroutines2 boost::CO2 的标准化和取舍​
• goroutiens 的 c++版​
• 可挂起函数
• 建模: 2个动态过程(如线程)的交互合同订立基础标准​

从C语言角度看C++ coroutines​
三个重点​
• second stack frame​
• __builtin_coro_resume​
• __builtin_coro_suspend​
LLVM coroutins​
https://llvm.org/docs/Coroutines.html​
• C++​
• Rust​
• Webassembly

C++ Coroutines support builtins​


• void __builtin_coro_resume(void *addr);​
• void __builtin_coro_destroy(void *addr);​
• bool __builtin_coro_done(void *addr);​
• void *__builtin_coro_promise(void *addr, int alignment, bool from_promise)​
• char __builtin_coro_suspend(bool final);​

例子, <coroutine> CLANG 简单实现​


C++
1 template <> struct coroutine_handle<void>
2 {
3 void resume() const
4 {
5 __builtin_coro_resume(ptr);
6 }
7 void destroy() const
8 {
9 __builtin_coro_destroy(ptr);
10 }
11 bool done() const
12 {
13 return __builtin_coro_done(ptr);
14 }
15 // ...
16 protected:
17 void *ptr;
18 };
19 template <typename Promise> struct coroutine_handle : coroutine_handle<>
20 {
21 // ...
22 Promise &promise() const
23 {
24 return *reinterpret_cast<Promise *>(
25 __builtin_coro_promise(ptr, alignof(Promise), /*from-
promise=*/false));
26 }
27
28 static coroutine_handle from_promise(Promise &promise)
29 {
30 coroutine_handle p;
31 p.ptr = __builtin_coro_promise(&promise, alignof(Promise),
32 /*from-promise=*/true);
33 return p;
34 }
35 };
Other coroutine builtins​
• size_t __builtin_coro_size()​
• void *__builtin_coro_frame()​
• void *__builtin_coro_free(void *coro_frame)​
• void *__builtin_coro_id(int align, void *promise, void *fnaddr, void *parts)​
• bool __builtin_coro_alloc()​
• void *__builtin_coro_begin(void *memory)​
• void __builtin_coro_end(void *coro_frame, bool unwind)​
• bool __builtin_coro_param(void *original, void *copy)​

与普通函数的区别​
coroutines​ 普通函数​ 备注​
栈在 堆上​ 线程栈上​
哪里​
参数​ C++ C++ 大部分coroutines 参
数要传值​
1 std::future<> foo(bar_t 1 std::future<> foo(bar_t
2 { st& a)
3 co_return; 2 {
4 } 3 return;
4 }

lamb C++ 大部分coroutines


da​ lambda不能capture
variables
1 bar_t a;
2 foo_t b;
3
4 auto f = [=]()
5 {
6 //do something
7 return;
8 }
C++
1 bar_t a;
2 foo_t b;
3 auto f = [](bar_t a, fo
b)
4 ->std::future<>
5 {
6 //do something
7 co_return;
8 };

返回 C++ C++ 不能deduce返回类型​


值​
1 std::future<> foo() 1 auto foo()
2 { 2 {
3 co_return; 3 return std::future<>
4 } 4 }
5
6 // 下面在c++20 中非法​
7 // 这是stackful corouti
8 // 将来可能会实现??​
9 auto foo()
10 {
11 co_return;
12 }
13

分类​
stackless​ stackfull (假想代码) / Generic 备注​
Coroutines​
Lambd stackful
a​ coroutines 在lua
等脚本语言中支
持​
C++ C++ 假想代码在
c++20 中非法 ​
将来可能会实
1 auto fStackless = [](au
a)
1 auto fStackfull = [](auto
a)
现??​
2 -> generator<int> 2 {
3 { 3 co_yield a * a;
4 co_yield a * a; 4 }
5 } 5
6 6 std::future<> foo()
7 std::future<> foo() 7 {
8 { 8 auto yieldIt = fStackl
9 fStackless(1); ss(1);
10 co_return; 9 yieldIt();
11 } 10
11 generator<int> r = fSt
ckless(2);
12 co_return;
13 }

Functi C++ C++


on​
1 std::future<> foo() 1 auto foo()
2 { 2 {
3 co_return; 3 co_return;
4 } 4 }
5
6 //foo 是什么?​

• stackless​
• stackfull​
Coroutines 为什么​
解耦与建模:​
◦ 编译器级将动态过程封装为对象, 并提供和外界交互的基础规则​
◦ 很大程度上提高了函数式编程的适用性,现在函数可完成动态模型转换
◦ coroutines模式创建(库撰写)与库使用者分离良好​
◦ 提供了一种可能: 将并发同步问题限制在库(模式)的开发中, 减少库(模式)使用者对并发同步的需

性能: ​
◦ 充分利用编译器对local scope的优化能力​
◦ 标准建议编译器尽可能减少堆上栈的使用
◦ 大量减少对线程的需要
◦ 大量减少线程上下文切换的需要
高并发: ​
◦ 编译器级(LLVM built-in) 上下文切换; ​
◦ 大幅度减少锁的使用; ​
◦ 为尽可能用atomic替代锁提供基础​
易用性: ​
◦ coroutines的使用者逻辑符合常规同步思维​
◦ 减少传递不必要的参数或者减少全局变量
◦ 已经足够成熟 Microsoft 2019年推出 WindowsRT库大量使用, 取代MFC, C++/CRT​
◦ 异步数据可分段 co_yield (future 不能)​
Coroutines How​
Coroutines 编译器及库支持​

Coroutines 代码生成及调试​
gdb/lldb 最新版暂时还不支持 读取coroutins 栈中的变量​
常规线程栈
极简模型​
C++ C++
1 // 前台代码, 库的使用者写​ 1 // 后台库代码2 ​
2 T foo() 2 class P
3 { 3 {
4 //...... 4 waitable_t yield_value(auto&&)
5 w_t w; 5 {
6 float a = co_await w; 6 //......
7 //...... 7 }
8 co_yield 20.5; 8 void return_value(auto&&)
9 //...... 9 {
10 co_return 100; 10 //......
11 } 11 }
12 12 };
13

C++
1 // 后台库代码3​
2 // 侵入式​
3 struct T
4 {
5 using promise_type = P;
6 };
7
8 // 非侵入式 需 partial specify
std::coroutine_traits
9 template<>
10 struct std::coroutine_traits<T>
11 {
12 using promise_type = P;
13 };
C++
1 // 后台库代码1​
2 // waitable_t
3 struct w_t
4 {
5 bool await_ready()
6 {
7 return false;
8 }
9
10 void await_suspend(auto
coro)
11 {
12
13
__builtin_coro_resume(coro)
;
14 }
15
16 float await_resume()
17 {
18 return 0.9;
19 }
20 };
21

与ECMAScript6概念对比​
js 异步 ​ C++协程​ 备注​
await​ co_await​ 关键字​
yield​ co_yield​ 关键字​
Promise​ cppcoro::task<>​ 库​
Generator​ cppcoro::generaor<>​ 库​
AsyncGenerator​ cppcoro::async_generaor<>​ 库​
Promise.all()​ cppcoro::when_all(...)​ 库​
Promise.any()​ when_any(...)​ 自己写的​
Promise.prototype.then()​ f_then(...)​ 自己写的​
Promise.resolve()​ f_make_ready_task(...)​ 自己写的​
Promise.reject()​ f_make_exceptional_task(...)​ 自己写的​
Promise.race()​ f_xxx()​ 研究中​
JavaScript C++ 自己写的​

1 async (()=>{ 1 []() -> co_run_it_t {


2 //await ... 2 //co_await ...
3 //do_sth 3 //do_sth
4 })(); 4 }();

...​ ...​ ...​

相同点​
• 等待语义
• yield语义​
• 解决callback陷阱​
• when_all(...)​
• when_any(...)​
• 都是stackless的​
不同点​
透明度​ 线程​ 模式​ 同步等待​ 易用性​ Performan
ce​
C++协程​ 完全透明​ 多线程​ 高度可定制​ cppcoro::sync_ 中​ 高​
背后是sjlj​ 有时仍需要mutex等 cppcoro 里用 wait(...)​ std::ta 很多并发同
同步操作​ coroutine甚至实 sk<>​ 步可用
现了协作式 pendin atomic模
mutex, latch, g​ 型完成​
fence 及锁 ​
js 异步 ​ 不透明​ 没有线程概念​ ECMAScript标准 无​ 高​ 高​
V8实现可能使用了并 规定​ 取决于v8
发??​ • Promise​ 实现​
• Generator​
• AnsycGenerat
or​
• AsyncIterable​

You might also like