协程是什么
协程,即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态。协程可以在运行期间的某个点上暂停执行,并在恢复运行时从暂停的点上继续执行。(摘自于网络)

协程实现方式
1.使用c的奇技淫巧
例如Protothreads,使用switch/case 和static(全局变量)的方法。
举个例子:

int function(void) {
  static int i, state = 0;
  switch (state) {
    case 0: /* start of function */
    for (i = 0; i < 10; i++) {
      state = __LINE__ + 2; /* so we will come back to "case __LINE__" */
      return i;
      case __LINE__:; /* resume control straight after the return */
    }
  }
}

在多次调用会返回不同的结果,为什么?只是因为static的状态而对这个程序的运转产生影响。当然他有一些缺陷,具体缺陷需要自己研究了。
(摘自:http://coolshell.cn/articles/10975.html

2.setjump/longjump
wiki百科介绍了一个pcl非常轻量级的lib,使用setjmp/longjmp的方法进行协程切换,
当然里边最多的内容是处理上下文和处理signal。pcl地址(http://xmailserver.org/libpcl.html)

3.使用汇编,操作寄存器、控制程序运行。
这个是比较酷的方法。当然对于程序在CPU上如何运行要求比较高。尤其是对ESP,EBP,EIP寄存器指针的作用要求比较高。
这种方法在实现上更加的困难
Python的greenlet。通过将寄存器保存到栈,将栈内容copy to堆上的greenlet上来保存状态,而将greenlet copy to 栈上,
并恢复寄存器而完成协程切换。

(图为:保存系统栈到堆中)
协程的现状
        半死不活的协程
协程在windows、Linux都有官方实现,在一般大而全的介绍API的书中都会提到。在lua,python,ruby中都有实现。但是从来没有一个软件以为卖点,很少听到协程。而java这个东东干脆就没有这个东西。
为什么,我尝试着去从计算机的作用去解释这个事情。计算机运行靠的程序,从大面分有三种:
IO-bound和CPU-bound、混合类型。


CPU-bound:科学计算、数据挖掘的计算
个人认为CPU-bound类型的任务,协程很难去搀和是很显而易见的,任务流程按照设计很自然的进行流转,即使需要并行处理,也是线程、或者进程。协程仅仅是伪并行,不能充分使用多核技术。
引入他们,一不能并行,二引入了复杂度(其中函数作为运行实体,在单CPU上进行切换,还是比较难以理解的),总体而言这些都是不必要的。


IO-bound任务:比如webserver。fs server
而在多种多样IO-bound的任务中,比较适合的也就是实现了多路复用的慢速IO。在Linux环境上,epoll提供了多次IO通知,协程自行进行切换,上层应用无所知,在完全串行的代码中,完成了异步IO。
在windows,java中协程成为了鸡肋,因为他们相似的任务处理方式(IOCP和NIO),系统调用(java虚拟机)完成了IO之后,worker线程才会继续进行工作,完成后续操作。这样的运作方式,协程彻彻底底没有了用武之地。
python,这个胶水语言已经越来越活跃在编程的世界了,而几乎所有的程序理念都可以在这里找到生存的环境,包括协程,下边我会介绍大名鼎鼎的gevent。

混合类型的任务:网络数据库等
这种任务类型实在不好评判,但是因为协程的适应性较差,很难在这种任务中存活。

协程的威力
美妙的gevent,棘手的nodejs。
(我并不想引发争议,说一下nodejs的优点。nodejs是非常适合js 开发者味道的框架,因为它通过事件通知和js的语法完美结合)

gevent和nodejs在网络模块使用了相同的技术(单指Linux平台)libev,nodejs通过使用回调,在事件通知之后进行后续处理。
试想一下,一个web请求,之后有2次读写数据库,2次读写缓存,这样的一整个逻辑已经被分为5段,很不连贯很不符合我们人脑的思维方式。

而使用gevent,顺序的把逻辑写一下,而它通过封装send/recv的系统调用,并在这里进行判断切换,将IO异步化,非常漂亮。以此gevent获得了很高的性能。

posted on 2015-07-27 13:52  tom_zhao_vip  阅读(1197)  评论(0编辑  收藏  举报