Coroutine实现有感

转载 2012年03月28日 14:44:02

转载:http://www.douban.com/note/11552969/


今天在debug的过程中顺便翻看了wikipedia的Coroutine条目,简单了解一下coroutine的实现机制:
Coroutine其实仍然是串行运算,并不是真正意义上的并行计算。因此coroutine不会有传统并行计算的访问冲突。
Coroutine的实现方式可以分成两种,
第一种是借用C的Stack作为每个Coroutine的Stack空间,这种方法最为简单,在Unix/Linux下有getcontext(), setcontext(),windows下有fiber来使用或者使用setjump和longjmp。但是由于桟空间是又编译器来分配的,所以如果有大量的coroutine存在的情况下,会造成大量的桟空间的浪费,并且setjump和longjmp会造成很大的cache miss。
第二种是采用虚拟机的方式,对于大部分的虚拟机来说往往采用全局桟的方法来进行函数调用,例如lua,这种情况下创建多个coroutine的桟空间的开销就会非常小,并且保存和记录返回link的开销也会比较小,因为你不需要保存register set等等需要保证task切换的东西。

第一种实现方式往往称为Stackfull 如我最近在看的Io,而第二种方式则称之为stackless因为没有桟开销如stackless python,erlang

另外一个比较有意思的话题是coroutine yield的行为应该是什么样子的
我认为可以有两种方式:yield to last,这种情况下谁调用了这个coroutine执行函数,那么当被调用者yield的时候将会返回给这个调用方,这种方法可以实现安generator或者iterator,可以参考python,注意generator并不不需要进行task switch而是简单的返回结果

另外一种是yield to scheduler,就是scheduler将会知道当前有多少正处在yield状态的coroutine,然后根据优先级或者某种机制去resume这个coroutine的执行,这种方法可以扩展很多其他的并行函数,例如Sleep,BeNice,隐含的async io等等,据我所知Io和stackless python就是采用这种方式的实现。

但是这两种做法其实并不冲突,可以认为每个coroutine保存了一个yield to地址,当被其他coroutine resume的时候需要保存这个地址用来返回,但是要是被scheduler resume的时候这个地址并不需要被修改,例如:

Yield To Other:
coroutine Producer
    produce one product
    yield Consumer

coroutine Consumer:
     use one product
     yield Producer

Yield To Scheduler:
coroutine Producer
     produce one product
     yield

coroutine Consumer:
    use one product
    yield

while( Scheduler.yieldCoro > 1 ) Scheduler.getNextCoro resume

more complex one :)

coroutine Producer
     receive from network // async function, will yield this coro immediately
     yield Consumer // ok data is ready, let consume start

coroutine Consumer
      use one product
      sleep(30) // start to sleep, give producer a chance to receive from network
      yield Producer

while (Scheduler.yieldCoro > 1) Scheduler.getNetCoro resume // scheduler will skip consumer while it's sleep. and it won't ask producer to run again because after producer is at yield to consumer, not to yield to scheduler. that means only consumer able to resume the producer.


方法多态与Duck typing;C#之拙劣与F#之优雅

文 / 李博(光宇广贞)方法多态与类型多态       了解 OOP 的同学对类型多态都很熟悉了。话说,类型多态之多态便体现在方法上,那方法多态又是嘛玩儿?类型多态之类型指的是对像的类型,其方法是受对...
  • hikaliv
  • hikaliv
  • 2009年09月16日 18:52
  • 4174

Continuation 异步化机制

Jetty 的 Continuation 机制 讨论 Jetty 的 Continuation 机制,首先需要提到 Ajax 技术,Ajax 技术是当前开发 Web 应用的非常热门的技术,也是 Web...

Coroutine in Java - Quasar Fiber实现-优

转自 https://segmentfault.com/a/1190000006079389?from=groupmessage&isappinstalled=0 说到协程(Coroutine),很...
  • mawming
  • mawming
  • 2016年08月31日 15:27
  • 1543

UNITY3D 实现暂停(Coroutine)

前断时间在做一个游戏项目,为了实现暂停还有游戏逻辑中用yield,自己写了一个类。代码如下: using UnityEngine; using System.Collections; // ...
  • qn9663
  • qn9663
  • 2012年09月28日 19:40
  • 716

Qemu中coroutine机制的实现

最近在看virtio的代码,看到virtio后端时发现在Qemu处理IO的时候使用了coroutine,之前对coroutine不了解,因此专门找了点资料学习并分析了下Qemu中的实现,于是做个笔记。...

Linux下c实现协程-Coroutine

Widnows 是提供了用户级线程的,类似 coroutine 需要用户主动是切换。这在单线程程序中非常有用。线程调度模块只负责提供堆栈,环境的保存。不负责分配时间片等。 自己实现 coro...

实现unity的协同(Coroutine)

要用c#实现unity的协同,现需要了解c# 的yield用法. 为了简明起见,先上一个简化版本,只实现不带停止功能部分(即没StartCoroutine("xxx")和StopCoroutin...

实现LUA脚本同步处理事件:LUA的coroutine

转自:http://www.cppblog.com/kevinlynx/archive/2015/05/12/58636.html 需求     受WOW的影响,LUA越来越多地被应用...

coroutine实现注解

//看了一个云风实现的coroutine c版本,注释了一下。(by kevin) //============================================== #ifndef ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Coroutine实现有感
举报原因:
原因补充:

(最多只允许输入30个字)