C++ coroutine-ts 怎么用-Part 2 coroutine有什么用

上一篇说了coroutine的本质是什么,就是resumable function,那么一个函数有了suspend和resume功能以后,会打开什么样的新世界大门呢?随便举几个例子。html

  • 函数每次被唤醒,就丢出一个值,而后暂停——这是generator
  • 函数启动一个IO操做,注册IO操做完成时唤醒本身,而后暂停——这是async-await
  • 函数开启一个管道,暂停,另外一个函数往管道里写一点东西,而后唤醒它——这是channel
  • 函数检查某个值是否是指望的,若是不是,就暂停——这是exception

其实,2和3的机制是很类似的,只不过2里面唤醒coroutine的是操做系统的callback,3是你本身的另外一个线程。4里面说的异常,其实就是这样的,由于异常和coroutine再往下追溯,他们的理论基础都是CPS(Continuation Passing Style),也就是把当前操做的后续操做做为闭包传给当前操做,而当前操做能够选择执行哪个(或是否执行)后续操做。虽然coroutine和exception都用到了CPS,但大部分的coroutine都额外支持了exception,耦合在了一块儿,由于他们没有直接提供操做continuation的东西。程序员

扯远了,能够看到了,coroutine解锁了不少写代码的新姿式。多线程

有了generator,你能够生成一个惰性求值的列表,对他进行变换,而这些全部的操做都是惰性执行的,这就是C#里面的LINQ,Python和Javascirpt里的生成器,Java8的Stream API,C++的range-ts也能够接入coroutine,而避免使用复杂的迭代器封装状态。闭包

有了async-await,你能够把异步代码写成像同步代码那样,而代码在await的边界处是自动暂停和继续的,这无疑下降了程序员手动写状态机维护状态的难度,也避免了一连串.then形成回调地狱的问题。channel和异步操做的async-await很类似,两条线程现在能够主动的暂停本身和唤醒对方,经过一个普通的原子变量来传递信息,而不须要用厚重的管道或者多线程同步机制来等待和唤醒对方。异步

关于coroutine模拟exception,这却是没有太大的必要,不过,考虑到coroutine的本质是CPS,那么就能够用coroutine来模拟rust的自动向上传播错误码,haskell的maybe monad等等,这些东西是对应语言的错误处理机制,就像C++的异常同样。async

脑洞,反过来,异常能够模拟coroutine吗?不行,异常有点像暂停以后不再会唤醒的coroutine。函数

相关文章
相关标签/搜索