美文网首页
coroutine的一些问题

coroutine的一些问题

作者: zizon | 来源:发表于2017-11-27 23:54 被阅读0次

    为了绕开繁琐的发布流程,选了python套hadoop的pb做rpc.
    主要还是走coroutine的方式.

    在一些场景夹杂了callback.
    主要是为了一个逻辑里访问访问多个不同服务的时候尽可能得减少block.

    只是单纯yield的话,叙事还是单线条的.

    比如从yarn拿一批application的信息过来,然后拿对应的配置文件路径,然后读写.

    纯粹coroutine的话,大概就是for一下application然后逐个yield getconfig.
    再发起read请求,继续yield.

    这样的话,至少理论上可以并行发出去的请求只能串行等待了.

    当然,一个折中的办法是阶段batch得yield.
    就像做map reduce一样,人为分出synchronize point去集中batch yield一个stage.

    而且从实现上来说,考虑到coroutine是单线程形式.
    要从非IO流程激活IO流程只能人为再加一个yield先切出去给IO一个启动的机会再切回来.

    这多多少少不是很符合直觉.

    而比较intuition的做法就是直接加callback.
    毕竟when ready的语义算是最少认知负担的了.
    并且天然地就是一条条并行的处理流水线形式.

    尽管实现上并没有什么太本质的区别.

    callback的另一个好处或者说coroutine容易犯的一个错就是context的有效性问题.

    从形式上来说,callback是一个limited的environment.
    所以会比较容易地迫使去带入context,并保持其有效.
    至少从个人习惯上来说是这样.

    但写coroutine的时候容易有一个错觉.
    就是天生的单线程线性形式.
    容易陷入写串行代码的一个思路.

    比如以写blocking IO的风格写coroutine.

    一个例子就是直接持有self.stream去反复做读写.

    这里的一个问题在于虽然coroutine保持了代码组织层面的线性执行.
    但实际上来说,每一次yield触发的都是隐性的context switch.

    也就是说,yield前后的reference指向就存在类似多线程情况下的concurrent modification问题.
    上下两行代码的实际指向存在差异.

    尽管这个可以从一个local reference来解决.
    但始终无法规避前后状态会有不一致的形式的存在.

    而这个对于coroutine作为提供一种简化的并发编程模型的初衷是有所违背的.

    并且,为了尽可能地enforce这种local reference的做法.
    在相关的API调用的接口设计上就可能需要显示的要求传入需要的context.

    当然,这可能只是个风格取舍问题.

    不过至少从这个层面上来说,跟callback的隔离机制还是某种程度上一致的.

    但至少从简化模型的层面来说,coroutine算是没有什么意义的.

    因为并行模型的核心要就是并行处理.
    强行地约束成一个线性执行条件/形式的话,多多少少算是一种自欺欺人的方式.

    相比之下,goroutine算是一种比较好的折衷方式.

    原始的callback的when ready虽然是最符合直觉的.
    但也存在为人诟病的组织形式上的嵌套callback hell的问题.

    虽然可以通过注册一种binding/routing的形式,减少这种欠优雅性.
    但随之而来的是叙事流程上的打散,重构,再打散的反复过程.

    一个例子就是event机制.

    形式上来说,就是通过一个key或者envelope去做mail routing.

    相对于直接的when ready来说,感觉上多了一层可有可无的多余描述.
    因为本质上来说,event名称成为了具体流程的一个代号索引.

    而这个索引,在很多语言和实现里是有些无谓的.

    作为对比的goroutine.
    形式上就是去掉了不必要的key索引的event dispatcher.

    事实上,从意图上来说就是把blocking的东西从当前执行环境移除.

    这一点跟coroutine来说,算是一种哲学层面的不同.

    因为coroutine虽然同样是基于把booking从当前环境移除的理念.
    但做法上是为了保持线性模型.

    而goroutine则更像是纯粹的把blocking的东西扔出去彻底不做.
    目的是保持当前执行流程里不存在可能阻塞的东西.
    然后在实现上提供一个双生的环境,只做blocking的东西.

    从直觉上更符合硬件形式.
    把实际的IO等操作offload到外围并行设备处理.

    相关文章

      网友评论

          本文标题:coroutine的一些问题

          本文链接:https://www.haomeiwen.com/subject/iqnjbxtx.html