Eventlet是什么
简单来说,Eventlet 是使用协程-coroutines(绿色线程-Green thread), 处理网络IO的非阻塞式的框架。
重要概念
- 协程-coroutines
- 一个线程可以启动多个协程,多到成千上万。
- 同一个时间点,只能有一个协程是执行状态,其他协程等待。
- 同一个线程范围内的协程可以切换执行。
- 它们共享线程的所有资源,因为互相之间没有冲突,而不用加锁。
- 非阻塞式IO
- 简单来说就是, 在处理多个IO请求的过程中,不会因为某个IO请求的读写没有就绪而一直处于等待状态,使其他IO请求无法处理。
- 更详细的内容会参考APUE单开一篇文章进行描述。(TBD)
绿化补丁
所谓绿化,即令系统网络模块中指定的模块协程友好(greenthread-friendly)。Python原生标准库不支持eventlet的协程,为此eventlet提供了patch。如果想在自己的应用程序中使用eventlet,就必须显示的绿化应用中要引入的模块。
同时设置socket为非阻塞式的。
使用Eventlet库的应用程序,必须使用以下两种方式之一,显示的执行绿化操作:
通过从
eventlet.green
引入网络处理相关的库绿化应用程序123from eventlet.green import socketfrom eventlet.green import threadingfrom eventlet.green import asyncore使用
monkeypatch
在全局中绿化指定的系统模块123456789101112'''该函数使用绿化后的对应函数,替换系统模块中对应的网络处理模块。'''eventlet.patcher.monkey_patch(os=None, select=None, socket=None, thread=None, time=None, psycopg=None)# 如果不指定参数,默认绿化所有系统模块。import eventleteventlet.monkey_patch()# 替换部分模块import eventleteventlet.monkey_patch(socket=True, select=True)
主要的模块
backdoor – Python interactive interpreter within a running process
backdoor
模块用来可以方便的查看一个长时间运行的进程的状态。它提供了普通 Python 解释器的交互式执行的使用方式,而又不会阻塞应用程序的执行。这对于debug、性能调试等是很有用处的。
在应用程序中,以这样的方式在一个处于监听状态的socket上启动一个 backdoor_server
:
|
|
运行起来后,可以通过 telnet 指定端口访问 backdoor
:
|
|
backdoor
可以与应用程序中的 yield 配合,转向指定的运行中的协程,所以就算在协程切换频繁的应用程序上使用 backdoor
, 也可以通过 Python 解释器的命令查看程序内部的状态。
backdoor
主要方法和类
|
|
corolocal – Coroutine local storage
|
|
debug – Debugging tools for Eventlet
db_pool – DBAPI 2 database connection pooling
event – Cross-greenthread primitive
class eventlet.event.Event
是若干协程之间用来通信的事件。Event 类似 Queue,只保存一项数值作为传递的结果。但二者之间存在如下两点差异:
- 调用
send()
方法时,当前协程不会马上被终止执行,只有当前线程执行完毕后,hub才会切换到其他线程。 send()
方法只能被调用一次;如果想再次send得再创建一个Event。
Event事件是协程之间交互的手段,也是 GreenThread.wait()
实现的基础:
|
|
Event类的主要方法
- ready()
如果调用 wait() 方法马上返回时返回True。用来避免等待耗时过长的任务而超时。比如,使用一个列表保持多个事件,调用 ready() 方法反复地访问这些事件直到其中一个返回True,这时我们就可以 wait() 到这个事件上了。
- send(result=None, exc=None)
根据 result 编排等待队列中的执行计划(顺序),然后立即返回到父协程(hub)。
|
|
多次 send() 同一个Event事件会报错
|
|
- send_exception(*args)
与 send() 方法相同,只不过是向 waiters 发送异常
|
|
- wait()
等待,直到其他协程调用 send() 方法,返回其他协程调用 send() 方法传入的参数。
|
|
当等待的事件已经发生时,马上返回
|
|
greenpool – Green Thread Pools
class eventlet.greenpool.GreenPool(size=1000)
free()
返回池中可用的协程的数目。如果数目为0或更少,下一个 spawn() 或者 spawn_n() 方法调用会将调用协程阻塞直到有一个协程变为可用。imap(function, *iterables)
针对可迭代对象iterables中的每一项,调用function函数进行处理。
比如,该方法处理文件中的每一行特别方便
|
|
resize(new_size)
在任何时间点更新协程池的最大可用数目。running()
返回GreenPool中,当前正在执行functions的协程数目。
spawn(function, args, *kwargs)
启动一个新的协程,以参数args和kwargs运行function。返回值是运行function的GreenThread对象,从该对象可以获取function执行的返回值。如果GreenPool中协程数目达到最大值,spawn 会被阻塞执行,直到运行中的协程有一个完成运行并释放一个协程池slot。function是可再进入的,function中可以在相同的pool中再调用spawn方法,不必担心死锁。
spawn_n(function, args, *kwargs)
和spawn一样,启动一个协程运行function。不同的是spawn_n没有返回值,也拿不到function执行的结果。starmap(function, iterable)
This is the same as itertools.starmap() and imap(function, *iterables).waitall()
Waits until all greenthreads in the pool are finished working.waiting()
Return the number of greenthreads waiting to spawn.
greenpool – Green Thread Pools
class eventlet.greenpool.GreenPile(size_or_pool=1000)
GreenPile 是对若干IO相关任务的抽象描述。一个 GreenPile 是由一个已存在的 GreenPool 对象构成。一个 GreenPool 对象可以有多个相关联的 GreenPile。
GreenPile 也可以单独创建,不与任何 GreenPool 对象有关,创建的时候传入整数值的size作为参数。
next()
等待下一个结果,挂起当前协程直到available。当不再有结果返回时抛出异常 StopIteration。spawn(func, args, *kw)
Runs func in its own green thread, with the result available by iterating over the GreenPile object.
greenthread – Green Thread Implementation
class eventlet.greenthread.GreenThread(parent)
pools - Generic pools of resources
queue – Queue class
semaphore – Semaphore classes
timeout – Universal Timeouts
websocket – Websocket Server
wsgi – WSGI server
eventlet.green.zmq – ØMQ support
eventlet.green.zmq – ØMQ support
排版好乱,喵了个喵……