python eventlet

Eventlet是一个Python库,通过协程(GreenThread)实现并发。它提供了多种API,如spawn、spawn_n、spawn_after等创建和控制协程,以及GreenPool线程池。协程具有独立栈、顺序可控、无需锁等优点,常用于高性能Web服务器和爬虫。Eventlet还通过补丁方法绿化Python的标准库函数,使其支持协程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Eventlet(http://eventlet.net/)是一个python的网络库,他可以通过协程的方式来实现并发。Eventlet协程又称GreenThread(绿色线程),所谓的并发,就是创建多个GreenThread,并对其进行管理,以实现非阻塞式的I/O。比如说用eventlet可以很方便的写一个性能很好的web服务器,或者是一个效率很高的网页爬虫,这都归功于eventlet的“绿色线程”,以及对“绿色线程”的管理机制。更让人不可思议的是,eventlet为了实现“绿色线程”,竟然对python的和网络相关的几个标准库函数进行了改写,并且可以以补丁(patch)的方式导入到程序中,因为python的库函数只支持普通的线程,而不支持协程,eventlet称之为“绿化”。Openstack中的大部分项目都采用所谓的协程(coroutine)模型。

1.什么是协程

协程与线程差不多,也就是一条执行序列,拥有自己独立的栈,局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。线程与协同程序的主要区别在于,一个具有多线程的程序可以同时运行几个线程,而协同程序却需要彼此协作地运行。就是说,一个具有多个协同程序的程序在任何时刻只能运行一个协同程序,并且正在运行的协同程序只会在其显示地挂起时,它的执行才会暂停.

2.协程优点

  • 每个coroutine有自己私有的stack及局部变量
  • 同一时间只有一个coroutine在执行,无需对全局变量加锁
  • 顺序可控,完全由程序控制执行的顺序。而通常的多线程一旦启动,它的运行时序是没法预测的,因此通常会给测试所有的情况带来困难。所以能用coroutine解决的场合应当优先使用coroutine。

3.几个主要API的理解

3.1 Greenthread Spawn(spawn,孵化的意思,即如何产生greenthread)

主要有3个函数可以创建绿色线程:
* 3.1.1 spawn(func, *args, **kwargs):创建一个绿色线程去运行func这个函数,后面的参数是传递给这个函数的参数。返回值是一个eventlet.GreenThread对象,这个对象可以用来接受func函数运行的返回值。在绿色线程池还没有满的情况下,这个绿色线程一被创建就立刻被执行。其实,用这种方法去创建线程也是可以理解的,线程被创建出来,肯定是有一定的任务要去执行,这里直接把函数当作参数传递进去,去执行一定的任务,就好像标准库中的线程用run()方法去执行任务一样。
* 3.1.2 spawn_n(func, *args, **kwargs):这个函数和spawn()类似,不同的就是它没有返回值,因而更加高效,这种特性,使它也有存在的价值。
* 3.1.3 spawn_after(seconds, func, *args, **kwargs):这个函数和spawn()基本上一样,都有一样的返回值,不同的是它可以限定在什么时候执行这个绿色线程,即在seconds秒之后,启动这个绿色线程。

3.2 Greenthread Control

  • 3.2.1 sleep(seconds=0):中止当前的绿色线程,以允许其它的绿色线程执行。
  • 3.2.2 eventlet.GreenPool:这是一个类,在这个类中用set集合来容纳所创建的绿色线程,并且可以指定容纳线程的最大数量(默认是1000个),它的内部是用Semaphore和Event这两个类来对池进行控制的,这样就构成了线程池。
    其中,有几个比较重要的方法:
  • running(self):返回当前池中的绿色线程数
  • free():返回当前池中仍可容纳的绿色线程数
  • spawn()、spawn_n():创建新的绿色线程
  • starmap(self, function, iterable)和imap(self, function, *iterables):这两个函数和标准的库函数中的这两个函数实现的功能是一样的,所不同的是这里将这两个函数的执行放到了绿色线程中。前者实现的是从iterable中取出每一项作为function的参数来执行,后者则是分别从iterables中各取一项,作为function的参数去执行。如:imap(pow, (2,3,10), (5,2,3)) –> 32 9 1000,starmap(pow, [(2,5), (3,2), (10,3)]) –> 32 9 1000

  • 3.2.3 eventlet.GreenPile
    这也是一个类,而且是一个很有用的类,在它内部维护了一个GreenPool对象和一个Queue对象。具体参加官方API&docs

  • 3.2.4 eventlet.Queue
    参见官方文档

3.3 Patching Functions(补丁方法)

这里就是之前所说的“绿化”,经过eventlet“绿化”过的模块都在eventlet.green中,导入他们主要有两种方法:
* 3.3.1 from eventlet.green import … + import_patched(module_name,*additional_modules,**kw_additional_modules),如:

from eventlet.green import socket
from eventlet.green import SocketServer
BaseHTTPServer = eventlet.import_patched('BaseHTTPServer',
                        ('socket', socket),
                        ('SocketServer', SocketServer))
BaseHTTPServer = eventlet.import_patched('BaseHTTPServer',
                        socket=socket, SocketServer=SocketServer)

这种方法有个缺陷就是不支持“延迟绑定”(late binding),比如在运行时导入模块。
* 3.3.2 monkey_patch(all=True,os=None, select=None, socket=None,thread=None,time=None,psycopg=None),如:

import eventlet
eventlet.monkey_patch(socket=True, select=True)

参考

http://blog.csdn.net/hackerain/article/details/7836993

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值