无栈协程本质是个可多次执行的状态机.一般使用协程的标准流程是,生成一个状态机,返回状态机的(协柄)句柄,通过控制该句柄,不断反复执行(恢复).
执行过程中,该状态机作用是:不停产生数据并写到某个地方.所以c++20协程提供了协产和协中,同时,每个协程都应有个实现了产生值或中值函数的,承诺类型的承诺对象.
同时,每次把数据写到承诺类型后,协程都会有一个暂停机会,方便外部取走数据.
于是协产 式并不等价于承诺.产生值(式),而是等价于协待 承诺.产生值(式),协待就是用来处理暂停的.
类似,协中 式也不等价于承诺.中值(式),而是等价于承诺.中值(式)后,再协待 承诺.终挂起()(中间有个析构过程).
那么,协待是怎么处理暂停的呢?对协待 式来说,式一般是一个等待器(也可通过一些规定好的函数转换成等待器),等待器实现了两个函数,直接协和挂起协.
直接协定义是不是真需要暂停协程,挂起协定义暂停协程后,继续去执行什么,可以是回到调用者,也可是启动另一个协程,还可继续执行当前协程.
通过挂起协返回协程句柄去启动协程时,当前调用者是不变的.
只有显式调用恢复或创建协程并直接执行,调用者才会改变.
在此,大体已完成了协程框架.但,还有很重要的一点.
协程最重要作用,就是不断把数据写到承诺对象.但是,如何把数据从承诺对象中取出呢?
最简单的是,闲着.如,把数据写到了承诺.值中,直接通过承诺.值取就够了.
不过,c++20的协程还提供了,帮助简化从承诺对象取数据过程的额外(恢复协)机制:
标准规定,当协待 等待器时,等待器还会实现恢复协函数,该恢复协的返回值,就是整个协待 等待器的返回值.
一般,在定义协程时,还会定义从协程到等待器的转换,于是,如果A协程想要从B协程中取数据,就可直接通过协待 其他协程实现,非常方便.