博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于协程
阅读量:7127 次
发布时间:2019-06-28

本文共 1998 字,大约阅读时间需要 6 分钟。

协程是什么

协程,即协作式程序,其思想是,一系列互相依赖的协程间依次使用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的状态而对这个程序的运转产生影响。当然他有一些缺陷,具体缺陷需要自己研究了。

(摘自:)
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获得了很高的性能。

转载于:https://www.cnblogs.com/tom-zhao/p/4679951.html

你可能感兴趣的文章
springboot集成mqtt
查看>>
重拾css(3)——学习css的思路
查看>>
SegmentFault 社区访谈 | 有位公子在奇舞
查看>>
jQuery源码分析之jQuery的定义
查看>>
一些经典面试题分析(上)
查看>>
[JS相关的记录01] 那什么来面对你,面向对象编程(__proto__,prototype,constructor以及原型链)...
查看>>
夏日葵电商:搭建一个商城系统,N+功能方案揭秘!
查看>>
Akka系列(一):Akka简介与Actor模型
查看>>
yii2获得从数据库获得数据的方法并处理
查看>>
Android开发百度地图(一)之初体验
查看>>
微服务指南走北(四):你不愿意做微服务架构的十个理由
查看>>
CSS代码重构与优化之路
查看>>
使用 sigprocmask 和 sigpending 在程序正文中捕获和处理信号
查看>>
Bodymovin插件的使用
查看>>
详细深入分析 Java ClassLoader 工作机制
查看>>
关于设计模式
查看>>
对一个“老”架构的重新思考
查看>>
DoubanFMPlayer, A mimic of Douban.fm player
查看>>
埃森哲、亚马逊和万事达卡抱团推出的区块链项目有何神通?
查看>>
2019年自动驾驶5大趋势预测:第一台Level 5 无人车问世
查看>>