• python协程及应用(一):简介


    前言:我一直在关注如何让开发变得更容易,效率更高,更不易出错。之前做过类似的努力,结合SOA和工作流引擎做的一个流程编辑:http://blog.csdn.net/chgaowei/article/category/597366。它有它自身的缺陷:脚本和程序之间的耦合太大,脚本限制太多。
    后来接触并且学习Python,它简洁而强大,应该是解决这类问题的一个思路。那天看到Python自带的生成器yield关键字,感觉着应该是解决逻辑问题的一个突破点(后面会介绍)。再后来参加Python con2011 china,看里面很多人提到了协程和Greenlet,特别是赖勇浩提出的口号:协程才是未来。当时很兴奋,我一直思考的问题有了解决方案。
     协程是什么?
    可以参考一下维基百科:http://zh.wikipedia.org/wiki/%E5%8D%8F%E7%A8%8B
    我之前写过一篇文章:并发编程学习总结也提到过。我认为这个定义也许更加贴切:“编程语言提供的一种并发机制”。
    先让我们来看一下进程和线程。
    未来让计算机能够同时处理多个任务,操作系统有了进程的概念,而且在进程内部,基本可以认为当前系统只有一个进程在运行,操作系统对此作了非常好的封装。进程间的切换是有操作系统来完成的。
    进程有一个问题,就是进程间切换耗费计算机资源非常大,而且申请一个新的进程的成本也非常高。所以后来就有了线程,它生成的成本和切换的消耗都比进程要低很多,而且线程间通信也非常方便。
    线程的问题是:1)存在线程安全问题,出了问题非常不易定位。2)进程内部有线程数目的限制。3)随着并发量的增加,线程生成和切换的成本也变得昂贵。
    解决并发还有一个方案是IO多路复用,它的效率确实非常高,但是代码复杂度也非常高:它把一个流程打散成一个个的节点,散落在多个地方,对开发和维护非常不利(这个是我们经常用的方案)。
     好,来看协程是如何解决这些问题的:
    1)协程的生成成本更低。其实就是一块内存,记录之前的调用的栈信息。你甚至可以通过控制函数调用的层次来进一步降低协程的大小。要生成一个协程,只需要申请一块内存并赋值。
    2)切换更快。基本是就是内存的拷贝的速度。
    3)没有线程安全问题。一个进程内可以同时存在多个协程,但是只有一个协程是激活的,而且协程的激活和休眠时程序员通过编程来控制,而不是内核来控制的。这样就没有了线程安全问题。
    4)可读性更好。相对于IO多路复用来说,你调用的服务接口或者IO接口是异步的,但是你的代码是流畅(顺序)的,并没有被异步和回调打乱。协程也是异步的,但是它会把异步的事件和回调封装起来,形成类似远程调用接口。
     一些资料:
    赖勇浩在pycon 2011 china上列举了一个node.js用异步实现的一块代码和Python协程风格的代码很能说明问题:http://www.slideshare.net/laiyonghao/python-webgame-10452102
    赖勇浩关于协程的文章非常不错,可以作为参考,可惜没有写完:协程三篇之一(协程初接触)
    赖勇浩自己也做了一个机遇Google protocol buffer和Greenlet的远程调用框架abu.rpc,有兴趣的可以参考一下(在写这篇文章之前,还一直没有抽出时间看一下)。
     提供协程机制的编程语言:
    现在很多语言都提供协程机制,或者通过第三方模块来实现协程。目前据我所知,支持协程的语言包括:Python,lua,erlang,go,io,ruby,c#等。我甚至还看到一些文章会在c中使用go和switch或者longjmp/setjmp来实现协程,不过很难再实际项目中使用。
     Python的协程实现:
    yield可以实现协程。另外,还有很多第三方的版本,比如greenlet。
     协程可以用来做什么?
    1)描述逻辑:我主要把协程用来描述逻辑。一个流程可能需要调用多个接口,其中很多接口是异步的。这样描述起来会困难一点。用线程是可以解决部分问题,但是复杂度提升。
    2)提高并发:主要应用在IO密集型应用中。gevent就是在greenlet基础之上的一个处理并发的框架,和上面的区别是,这里的事件及接口是IO接口。
     缺陷:
    无法使用多核。不过可以通过进程+协程来解决。
     
  • 相关阅读:
    zookeeper3.5.6单机集群环境搭建
    mycat分表
    myacat分片及全局表定义
    装饰器
    函数参数,作用域
    可变,不可变,无序, 有序
    dict
    列表可变,元祖不可变
    列表操作
    字符串find
  • 原文地址:https://www.cnblogs.com/chgaowei/p/2557175.html
Copyright © 2020-2023  润新知