协程和纤程

这个其实看vert.x会非常清楚

vert.x里面有两个线程池(缺省)如果你自己不再开线程池的话

一个是eventloop线程池,还有一个是worker thread pool线程池

协程(coroutine)和纤程(fiber)的主要区别点在于:调度

这两个单词都翻译得不错,coop协作,co就是协的词根,coroutine翻译成协程很巧妙

fiber是纤维,翻译成纤程,对应的thread/线程,process/进程,这几个单词翻译得都比较巧妙

说回coroutine和fiber

coroutine和fiber的差异点在于,两者的调度不一样,异步api在结果出来前,会释放当前线程,那么在此期间,当前线程就能去搞其他的计算活动,那一个最原始的异步api,一般是以带有callback的形式出现,但是callback有一个问题,就是写起来会变得混乱,因为callback要嵌套进参数里面去

如果多几层异步调用的话,就会形成缩进金字塔

那怎么办呢?一种解决方式就是通过声明continuation的scope,将scope里面的所有状态全部寄存,然后用continuation.yield释放当前线程,然后等结果出来之后,当前线程再从寄存器里取出状态,继续往前执行

那这里有几个问题,不一一列举,有兴趣的自己去搞懂这里面的机制,建议多看vert.x

有一个最重要的差别点就是,当这个结果出来之后,后续的代码,是由哪个线程在执行?

如果还是原来线程在执行,那么就是coroutine

如果存在有被其他线程所执行的可能,那就是fiber

这里可以看出来,fiber多了一个调度器,scheduler,所以一般fiber在启动的时候,会开一个carrier thread pool,线程池,大多数语言叫这个线程池叫做fork & join pool,既然是pool,那里面的线程不止一个,那fiber如果使用了异步操作,这里就有可能被一个以上的线程先后执行,注意这里是有可能,因为调度器有可能会把后续的步骤调度回原来的线程,但是这个完全由调度器决定

那这样做的好处是什么呢?客户在这里使用blocking code,因为这个流程基本上完全模拟了线程操作,线程在io时候是怎样被blocked,这里的纤程也会怎样被blocked

坏处是什么呢?嗯,跟线程一样,它需要一个完美的stack,线程就有自己的stack,那这个stack可能会比线程的stack要小,但是会比coroutine的stack要大很多,同时调度上也有一定程度的消耗,当然这个消耗可能不大,但还是有,因为可能被其他线程所执行,所以要在yield之前,把当前线程的所有状态全部寄存,否则resume的时候,状态丢了就完蛋了

那coroutine呢?coroutine则保证会使用原来的线程,所以会有eventloop的概念,node.js就用了eventloop,还有vert.x,那因为是原来的线程,那这里会有问题,一个是线程可能过度负荷,导致一个线程在忙,其他线程在观望的情况,所以这就出现了eventloop的一个坏处

那就是,你需要估算eventloop的执行时间,不能让它被blocked,这就对程序员提出了更高的心智要求

好处是什么呢?性能

因为都是同一个线程在执行,那么yield的时候,需要保存的状态就少了很多,kotlin里面一个coroutine的消耗才区区几百个字节,一般的fiber做不到这么低

同时因为调度的都是原来的线程,所以调度的损耗也减少了,所以总体而言,coroutine+eventloop的性能,要高过fiber+fork&join pool的性能,但是同时,对开发人员的心智要求,也相应提高了

说一下java的进度,java的loom正在如火如荼地开展中,vert.x已经实现了eventloop pool,但是目前java的语法,还只能实现future(monad)和callback两种api,还做不到await和scheduler,因为这两者的实现,都需要project loom的continuation yield/scope和scheduler这些,但是我们已经可以在kotlin中先行体验coroutine,其实也有fiber,用launch(common pool)加上缺省的调度器,就是fiber了

同时clojure也提供了core.async,也提供了fiber,缺省用的就是fork&join pool

所以还是要搞vert.x,否则这两者你没有办法完全体验到,像node,只有eventloop和await,没有fiber,像go就是强制使用goroutine(就是fiber),就没有coroutine,一般的java工具,还停留在thread阶段,只有vert.x这种多语言的工具,可以提前接触kotlin等语言,这些概念就都会出现


刚看到一个相关问题,应该说c++的boost是最早的fiber和coroutine的出处了

虽然不是java,但是java的概念也从中延伸而来,这个问题的高票答案也说到了

fiber带了一个调度器,coroutine则不带,java一样的

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盼盼编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值