eventlet学习笔记

标签(空格分隔): python eventlet


eventlet是一个用来处理和网络相关的python库函数,且可以通过协程(coroutines)实现并发。在eventlet里,将协程叫做greenthread(绿色线程),所谓并发,即开启多个greenthread,并对这些greenthread进行管理。尤为方便的是,eventlet为了实现“绿色线程”,竟然对python的和网络相关的几个标准库函数进行了改写,并且可以以补丁(patch)的方式导入到程序中,因为python的库函数只支持普通的线程,而不支持协程,eventlet称之为“绿化”。

eventlet主要基于两个库——greenlet(过程化其并发基础,简单封装后即成为GreenTread)和select.epoll(默认网络通信模型)。

1.greenlet

greenlet支持微线程(tasklet),tasklet伪并发运行,同步在信道上交换数据。

greenlet——coroutines(协程)——micro-thread(微线程)(三者意思相近)

在greenlet上可自定义微线程调度顺序,灵活掌控控制流。

(1)greenlet简介

greenlet之间可相互切换,当一个greenlet1切换至greenlet2时,greenlet1挂起,当greenlet2运行一段时候切换回时,greenlet2挂起,greenlet1恢复运行。

每个greenlet创建时拥有一个空的栈,当切换至该greenlet时,它会运行一个特殊函数(该函数也许会调用其它函数),当最终最外层函数执行完成后,greenlet栈再次为空,greenlet死亡。greenlet也可被不可捕捉的异常杀死。

(2)Parents

每一个greenlet有一个父greenlet,相应父greenlet在greenlet被创建时初始化。greenlet死亡后,父greenlet继续执行。

greenlet树形组织,隐含的main greenlet为此树根节点。任何一个greenlet死亡,执行顺序将被回溯至main greenlet。异常发生将传播至parent greenlet。

switch不是调用,只是在并行的'stack containers'中传输执行。

(3)实例化

greenlet类型greenlet.greenlet,有如下一些方法:

greenlet(run=None, parent=None)

创建一个新的greenlet对象但并不运行,run为可调用请求,parent为父greenlet,默认为当前greenlet。

greenlet.getcurrent()

返回当前greenlet。

greenlet.GreenletExit

此特殊异常不会传播至父greenlet,它被用于杀死一个单独的greenlet。

(4)切换

greenlet切换发生在switch()函数被调用或一个greenlet死亡时。调用switch

()函数的greenlet为切换至的目标greenlet;greenlet死亡时切换至parent greenlet。切换时,一个对象或异常发送至目标greenlet,这即是greenlets间方便的通信方式。例如:

def test1(x, y):
z = gr2.switch(x+y)
print z def test2(u):
print u
gr1.switch(42) gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch("hello", " world")

此段程序输出“hello world”和42.需注意test1()和test2()的参数并不是在greenlet创建时给出,而是在第一次切换到相应greenlet时给出。

g.switch(*args, **kwargs)

切换至greenlet g执行。

需要注意的是x = g.switch(y),会将对象y发送给g,然而稍后却有可能将毫无关联的对象经毫无关联的greenlet处理后返回给x。这可以理解为g.switch(y)的值没有立即返回,而其它greenlet的结果却先返回了!!!

switch至一个已经死亡的greenlet,最终将会switch至其parent greenlet或parent' parent greenlet,如此回溯。(最终的parent greenlet是main greenlet,永不死亡。)

(5)greenlets方法和属性

g.switch(*args, **kwargs)

切换至greenlet g执行。

g.run

执行后运行greenlet g,g运行后该属性不再存在。

g.parent

g的parent greenlet。该变量可写,但禁止构造循环型父子关系。

g.gr_frame

目前上层框架,或为None。

g.dead

当g死亡时值为True。

bool(g)

g处于活动状态时值为True,若死亡或还未开始值为False。

g.throw([typ, [val, [tb]]])

切换执行序列至greenlet g,在g中立即抛出给定异常。若未提供参数,异常默认为greenlet.GreenletExit。

(6)Greenlet和python线程

Greenlet能够和Python线程结合,每个python线程中包含一个独立的main greenlet及由其子greenlet构成的树。但不属于同一个线程的不同greenlet之间不能结合或切换。

参考文章:

【1】Eventlet documentation

【2】Openstack eventlet分析——溜溜小哥的CSDN博客

最新文章

  1. Python文件读写
  2. Kafka设计解析(五)- Kafka性能测试方法及Benchmark报告
  3. [转]Hibernate延迟加载与opensessioninviewFilter
  4. C#抓取网页HTML内容
  5. Myeclipse 操作数据库
  6. 第十一章:Android数据存储(上)
  7. Android常用查询网站
  8. POJ 1837 Balance 【DP】
  9. 【全国互虐】Fibonacci矩阵
  10. IOS文件存储小结
  11. Unable to resolve target 'android-8'类似错误的解决办法
  12. ajax和jsonp的封装
  13. A Swift Tour(3) - Functions and Closures
  14. Altium Designer10 如何导出Gerber文件
  15. uva 111 History Grading(最长公共子序列)
  16. Java OCR tesseract 图像智能字符识别技术 Java代码实现
  17. MDK下调试时提示AXF文件无法导入的解决方法(转)
  18. 用spark导入数据到hbase
  19. 零python基础--爬虫实践总结
  20. Linux删除/boot后该如何恢复

热门文章

  1. 在PL/SQL使用游标获取数据及动态SQL
  2. ajax接收处理json格式数据
  3. Gym - 101972B Arabella Collegiate Programming Contest (2018) B. Updating the Tree 树DFS
  4. Java Socket编程 深入讲解?你之前真的学懂了吗
  5. RocketMQ(2)
  6. [转]linux之pr命令
  7. java学习笔记_序列化
  8. es6杂记
  9. Redux 基础概念
  10. Android开发笔记(6)——类的设定与继承