最近在怒学coroutine

allegro
静水流深 09月14日 字数 1582

目前看到的比较好的两个系列的coroutine的文章,基本是零基础小白可以看的:

1. http://www.modernescpp.com/index.php/c-20-coroutines-the-first-overview

这是一个系列,不过每次读完没有下一篇的链接,你需要在旁边的blog archieve中寻找下一篇进入。

我会在这里贴出各篇链接:

1). http://www.modernescpp.com/index.php/c-20-coroutines-the-first-overview

2). http://www.modernescpp.com/index.php/c-20-coroutines-more-details

3). http://www.modernescpp.com/index.php/c-20-an-infinite-data-stream-with-coroutines

4). http://www.modernescpp.com/index.php/c-20-thread-synchronization-with-coroutines

5). http://www.modernescpp.com/index.php/c-20-coroutines-with-cppcoro

6). http://www.modernescpp.com/index.php/c-20-coroutine-abstraction-with-cppcoro

7). http://www.modernescpp.com/index.php/c-20-thread-pools-with-cppcoro

2. https://github.com/lewissbaker/cppcoro

看这个coroutine的STL辅助类实现,有很多例子,能给个第一印象。

目前貌似没有linux下面的网络实现,不过我看有人fork并实现了,用的liburing。不知道会不会merge。

这2个系列的文章都是从用户出发介绍stl支持,然后在介绍一些底层co_xx原语。

就像我们先学std::vector()再学底层operator new(), 比较友好。

3. https://lewissbaker.github.io/

这个是第二个系列的作者的blog,比较艰深,建议看完前两个系列再尝试。

我到目前为止只看了1)和2).其中2)有中文译文:https://juejin.im/post/6844903715099377672

1) https://lewissbaker.github.io/2017/09/25/coroutine-theory

2) https://lewissbaker.github.io/2017/11/17/understanding-operator-co-await

3) https://lewissbaker.github.io/2018/09/05/understanding-the-promise-type

4) https://lewissbaker.github.io/2020/05/11/understanding_symmetric_transfer

32 个回复
poocp
慢速随机指标 09月14日

这东西不难,有需求很容易学会,或者自己实现。

十多年前,我做的一个server程序,每个处理线程需要用一个lua脚本引擎完成处理逻辑,在脚本引擎里面还要调用PostgreSQL数据库接口。

然而lua提供的协程库功能不适合我,于是重新在lua中自己实现一套协程,而当时PostgreSQL的Lua接口也还没提供非阻塞的请求应答模型,所以那部分也要改,才在我的项目里把协程用起来。

allegro
静水流深 09月14日

公司的活没需求,公司的c++才到14,估计明年到17。

我学这种一般都套到自己的github上写的玩具里面去用以致学,年纪大了学新东西真是炒蛋啊。

c++20真是把类接口和c++语法耦合到了一个新高度。

然而lua提供的协程库功能不适合我,于是重新在lua中自己实现一套协程,而当时PostgreSQL的Lua接口也还没提供非阻塞的请求应答模型,所以那部分也要改,才在我的项目里把协程用起来。

【 在 poocp 的大作中提到: 】

: 这东西不难,有需求很容易学会,或者自己实现。

: 十多年前,我做的一个server程序,每个处理线程需要用一个lua脚本引擎完成处理逻辑,在脚本引擎里面还要调用PostgreSQL数据库接口。

Madlee
无竹居士 09月14日
hgoldfish
老鱼 09月14日

真心建议你们直接看代码,而不是在这些文章里面乱七八糟地学。

https://github.com/hgoldfish/qtnetworkng/blob/master/include/coroutine.h

https://github.com/hgoldfish/qtnetworkng/blob/master/src/coroutine_fcontext.cpp

https://github.com/hgoldfish/qtnetworkng/blob/master/src/context/asm/jump_i386_sysv_elf_gas.S

上面是我实现的协程,核心代码不超过一百行,剩下三百行都是些工具代码。

应用方面现在很多文章都是在教你怎么用 coroutine 实现 generator 或者简单的就是用 generator 实现功能,都是在技术这个圈里面打转。可以看看我是怎么把 coroutine 和 generator 应用到业务逻辑,简化软件的设计:

https://hgoldfish.com/blogs/article/85/

【 在 allegro (静水流深) 的大作中提到: 】

: 目前看到的比较好的两个系列的coroutine的文章,基本是零基础小白可以看的:

: 1. http://www.modernescpp.com/index.php/c-20-coroutines-the-first-overview

: 这是一个系列,不过每次读完没有下一篇的链接,你需要在旁边的blog archieve中寻找下一篇进入。

: ...................

GoGoRoger
GoGoRoger 09月14日

看一看腾讯的libco就知道了,实现方式都是大同小异。

发自「今日水木 on Mi Note 3」

【 在 allegro 的大作中提到: 】

: 目前看到的比较好的两个系列的coroutine的文章,基本是零基础小白可以看的:

: 1\. http://www.modernescpp.com/index.php/c-20-coroutines-the-first-overview

: 这是一个系列,不过每次读完没有下一篇的链接,你需要在旁边的blog archieve中寻找下一篇进入。

: 我会在这里贴出各篇链接:

: 1). http://www.modernescpp.com/index.php/c-20-coroutines-the-first-overview

: 2). http://www.modernescpp.com/index.php/c-20-coroutines-more-details

: 3). http://www.modernescpp.com/index.php/c-20-an-infinite-data-stream-with-coroutines

: 4). http://www.modernescpp.com/index.php/c-20-thread-synchronization-with-coroutines

: 待续

: 2\. https://github.com/lewissbaker/cppcoro

: 看这个coroutine的STL辅助类实现,有很多例子,能给个第一印象。

: 目前貌似没有linux下面的网络实现,不过我看有人fork并实现了,用的liburing。不知道会不会merge。

: 这两个系列的文章都是从用户出发介绍stl支持,然后在介绍一些底层co_xx原语。

: 就像我们先学std::vector()再学底层operator new(), 比较友好。

: --

howry
howry 09月14日

羡慕嫉妒啊

什么时候才能达到大佬这种境界啊

有个什么需求就能一下子实现出来

然而lua提供的协程库功能不适合我,于是重新在lua中自己实现一套协程,而当时PostgreSQL的Lua接口也还没提供非阻塞的请求应答模型,所以那部分也要改,才在我的项目里把协程用起来。

【 在 poocp 的大作中提到: 】

: 这东西不难,有需求很容易学会,或者自己实现。

: 十多年前,我做的一个server程序,每个处理线程需要用一个lua脚本引擎完成处理逻辑,在脚本引擎里面还要调用PostgreSQL数据库接口。

allegro
静水流深 09月15日

其实,coroutine的原理比c++20的syntax和实现更简单。

主要是学习c++20中如何引入这个coroutine,如何和当前的c++语法语义互动切入,这个更难。

【 在 GoGoRoger 的大作中提到: 】

: 看一看腾讯的libco就知道了,实现方式都是大同小异。

: 发自「今日水木 on Mi Note 3」

fanci
大葡萄 09月15日
GoGoRoger
GoGoRoger 09月15日

自己三两下就实现个协程?厉害,膜拜。

发自「今日水木 on Mi Note 3」

【 在 poocp 的大作中提到: 】

: 这东西不难,有需求很容易学会,或者自己实现。

: 十多年前,我做的一个server程序,每个处理线程需要用一个lua脚本引擎完成处理逻辑,在脚本引擎里面还要调用PostgreSQL数据库接口。

: 然而lua提供的协程库功能不适合我,于是重新在lua中自己实现一套协程,而当时PostgreSQL的Lua接口也还没提供非阻塞的请求应答模型,所以那部分也要改,才在我的项目里把协程用起来。

cooljay
随便起个不是那么长的名字就行 09月15日

这里大牛好多

【 在 allegro 的大作中提到: 】

: 目前看到的比较好的两个系列的coroutine的文章,基本是零基础小白可以看的:

: 1. http://www.modernescpp.com/index.php/c-20-coroutines-the-first-overview

: ....................

eematlab
一辰未冉 09月15日

coroutine要达到什么目的其实是很清晰

我自己用epoll和多线程都实现过类似的功能

但要理解c++20的coroutine还是很困难, 主要在于如何在c++的语义语法里做这个

c++提供的是一个半成品, 而讲coroutine的文章喜欢把其他语言里的概念搬进来(还讲不清),搞得人分不清哪些是c++里的, 哪些是其他语言里的

【 在 allegro 的大作中提到: 】

: 其实,coroutine的原理比c++20的syntax和实现更简单。

: 主要是学习c++20中如何引入这个coroutine,如何和当前的c++语法语义互动切入,这个更难。

allegro
静水流深 09月15日

所以我建议看看那个github下面的cppcoro的实现,README里面就有长篇类接口和实例。

如果知道啥是coroutine,再看看那些例子,就会有个第一印象了。

【 在 eematlab 的大作中提到: 】

: coroutine要达到什么目的其实是很清晰

: 我自己用epoll和多线程都实现过类似的功能

: 但要理解c++20的coroutine还是很困难, 主要在于如何在c++的语义语法里做这个

: ...................

lambdai
lambdai 09月15日

不建议初学者看。

这哥们是维护facebook folly,包括folly的future promise executor那块儿的。这个库基本上就是folly future api的coroutine的实现。

你再看看作者这个talk就知道这个库想解决什么问题了。https://youtu.be/1Wy5sq3s2rg 去年我没有coroutine基础的时候看,尽管我知道他想讲什么,我都完全跟不上那个视频的速度…

他blog的3篇倒是很有帮助,我打印下来看了。

如果是视频的话,我推荐这个 https://youtu.be/vDA925C55F0,尽管之前没听过这么一号人物

【 在 allegro 的大作中提到: 】

: 所以我建议看看那个github下面的cppcoro的实现,README里面就有长篇类接口和实例。

: 如果知道啥是coroutine,再看看那些例子,就会有个第一印象了。

: ....................

hgoldfish
老鱼 09月15日

我觉得 coroutine 就是为了把编程里面的所有异步逻辑都转换成契合人类思维的顺序同步逻辑。

只要把目前算法里面的各种异步都重新用顺序的办法思考一下,就很容易知道 coroutine 的使用场景以及实现原理。

【 在 lambdai (lambdai) 的大作中提到: 】

: 不建议初学者看。

: 这哥们是维护facebook folly,包括folly的future promise executor那块儿的。这个库基本上就是folly future api的coroutine的实现。

: 你再看看作者这个talk就知道这个库想解决什么问题了。https://youtu.be/1Wy5sq3s2rg 去年我没有coroutine基础的时候看,尽管我知道他想讲什么,我都完全跟不上那个视频的速度…

: ...................

allegro
静水流深 09月15日

coroutine本身容易理解,难理解的是C艹20把coroutine机制设计得如此复杂。

【 在 hgoldfish 的大作中提到: 】

: 我觉得 coroutine 就是为了把编程里面的所有异步逻辑都转换成契合人类思维的顺序同步逻辑。

: 只要把目前算法里面的各种异步都重新用顺序的办法思考一下,就很容易知道 coroutine 的使用场景以及实现原理。

likely
thinker 09月15日

C++11应该是首次开始耦合语法和类库接口吧,大方向是向Python等语言靠拢。

【 在 allegro 的大作中提到: 】

: 公司的活没需求,公司的c++才到14,估计明年到17。

: 我学这种一般都套到自己的github上写的玩具里面去用以致学,年纪大了学新东西真是炒蛋啊。

: c++20真是把类接口和c++语法耦合到了一个新高度。

: ...................

hgoldfish
老鱼 09月15日

因为 c++ coroutine 是没什么卵用的基础库,相当于 llvm ir 字节码的简单的映射。上面还必须搭一层事件循环才能真正用起来。

理解 c++ coroutine 其实是我们这些基础库程序员的责任,一般 c++ 用户不必去深究。

【 在 allegro (静水流深) 的大作中提到: 】

: coroutine本身容易理解,难理解的是C艹20把coroutine机制设计得如此复杂。

hanjiamajia
hanjiamajia 09月15日

因为c++20只是包含编译器需要实现的底层功能

真正的库最后讨论的时候冻结了啊,要c++23才能加进来

上面有朋友说的 cppcoro 就是类似的库呀

coroutine 的概念很简单,简单实现一个很容易

但是说实话你的那个库设计的真的不 modern 啊,简单看了下,接口设计感觉像很多年前的风格。

而且没有 async await 的协程现在已经没有什么使用价值了感觉

比如现在的 http 库至少应该像下面的样子(包含await 和 自动反序列化):

auto http_result<Model> r = co_await new http<Model>()->add_param("k","v")->add_header("k","v")->add_body("k","v").request("post");

Model m = r.result;

【 在 hgoldfish 的大作中提到: 】

: 因为 c++ coroutine 是没什么卵用的基础库。连 generator 都还没有,相当于 llvm ir 字节码的简单的映射。上面还必须搭一层事件循环才能真正用起来。

: 理解 c++ coroutine 其实是我们这些基础库程序员的责任,一般 c++ 用户不必去深究。

hgoldfish
老鱼 09月15日

对,我也觉得 coroutine 的实现很简单。关键在于理解 coroutine 的应用场景。经典的把 generator 用在编译器语法解析以及网络编程特别好用,不搞那些弯弯绕绕的 vistor/callback 模式。把 coroutine 用在 gui 编程也特别好用——这个领域我看目前最强的可能是 c#. js 和 c++ 社区都是稀烂。

你说的那一套 modern http 把序列化和反序列化和 http client 耦合起来了,还有流式 API 是 rxjava 那个流派的玩法。事实上,我有一套使用 qt 反射自动序列化和反序列化的未开源模块。不过我不想把它们做到一块来。我做的是简洁友好API的 http client,不是高性能,也不是 modern http client. 目标是让人一看就懂,用起来不容易出错。

【 在 hanjiamajia (hanjiamajia) 的大作中提到: 】

: 标  题: Re: 最近在怒学coroutine

: 发信站: 水木社区 (Tue Sep 15 17:11:56 2020), 站内

: 【 在 hgoldfish 的大作中提到: 】

: : 因为 c++ coroutine 是没什么卵用的基础库。连 generator 都还没有,相当于 llvm ir 字节码的简单的映射。上面还必须搭一层事件循环才能真正用起来。

: : 理解 c++ coroutine 其实是我们这些基础库程序员的责任,一般 c++ 用户不必去深究。

: :

: 因为c++20只是包含编译器需要实现的底层功能

: 真正的库最后讨论的时候冻结了啊,要c++23才能加进来

: 上面有朋友说的 cppcoro 就是类似的库呀

: coroutine 的概念很简单,简单实现一个很容易

: 但是说实话你的那个库设计的真的不 modern 啊,简单看了下,接口设计感觉像很多年前的风格。

: 而且没有 async await 的协程现在已经没有什么使用价值了感觉

: 比如现在的 http 库至少应该像下面的样子(包含await 和 自动反序列化):

: auto http_result<Model> r = co_await new http<Model>()->add_param("k","v")->add_header("k","v")->add_body("k","v").request("post");

: Model m = r.result;

: --