上次谈到了concurrent(http://bookjovi.iteye.com/blog/1333431),里面说到了Erlang和Go语言,今天再谈谈coroutine,在Erlang中process不能称为coroutine,同样Go中也避免了coroutine的用词,而直接改为goroutine,那么coroutine是什么呢?
关于coroutine在wikipedia中有着非常详尽的描述:http://en.wikipedia.org/wiki/Coroutine
coroutine和Erlang process/goroutine的最大区别是coroutine只能在一个线程中执行,所以不能算的上是真正的concurrent,coroutine中比较普遍的关键词是yield,在coroutine中只能主动放弃执行权,而不能被动抢占。
实现coroutine的语言有:lua, Perl 6(built-in), tcl(built-in)等。
Java中有coroutine吗?答案是在语言层次上是没有,不过可以通过其他方式,如修改JVM(http://openjdk.java.net/projects/mlvm/),期望jdk 8能加上这方面的特性(期望java concurrent特性的可以看看scala语言)。bluedavy有一遍关于java的coroutine文章,写的很好 http://blog.bluedavy.com/?p=4
其实有时coroutine用几行C代码就可以模拟了,看看“Coroutine in C”:
http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
int function(void) { static int i, state = 0; switch (state) { case 0: goto LABEL0; case 1: goto LABEL1; } LABEL0: /* start of function */ for (i = 0; i < 10; i++) { state = 1; /* so we will come back to LABEL1 */ return i; LABEL1:; /* resume control straight after the return */ } }
够酷吧!不用切换stack就模拟了简单的coroutine。
值得一提的是go语言的作者之一Russ Cox以前就写过C的coroutine库libtask(http://swtch.com/libtask/),怎么样?和go语言很像吧,从这个角度看,go就是把libtask移植到语言侧面了。
C的coroutine库还有很多:
https://github.com/halayli/lthread
http://www.dekorte.com/projects/opensource/libCoroutine/
http://www.goron.de/~froese/coro/
http://code.google.com/p/libconcurrency/
http://software.schmorp.de/pkg/libcoro.html
与coroutine概念相似的还有generator:http://en.wikipedia.org/wiki/Generator_(computer_programming)
generator在python, c#, ruby都有实现,用以实现简单的iterator
continuations概念和coroutine也很相似,我们看一个在mono中的continuations api:
public class Continuation { public Continuation (); public void Mark (); public int Store (int state); public void Restore (int state); } var c = new Continuation (); ... switch (c.Store (0)){ case 0: // First invocation case 1: // Restored from the point ahead. } ... // Jump back to the switch statement. c.Restore (1);
这个例子和上面那个coroutine in C 是不是很像啊?可以深层次的把continuation理解为C里面的setjmp和longjmp。
写的很乱!:)