Python——eventlet

eventlet语境下的“绿色线程”普通线程之间的区别:

  1. 绿色线程几乎没有开销,不用像保留普通线程一样保留“绿色线程”,每一个网络连接对应至少一个“绿色线程”;

  2. 绿色线程需要人为的设置使其互相让渡CPU控制权,而不是抢占。绿色线程既能够共享数据结构,又不需要显式的互斥控制,因为只有当一个绿色线程让出了控制权后其他的绿色线程才能访问彼此共享的数据结构。

下图是eventlet中协程、hub、线程、进程之间的关系:

 _______________________________________
| python process                        |
|   _________________________________   |
|  | python thread                   |  |
|  |   _____   ___________________   |  |
|  |  | hub | | pool              |  |  |
|  |  |_____| |   _____________   |  |  |
|  |          |  | greenthread |  |  |  |
|  |          |  |_____________|  |  |  |
|  |          |   _____________   |  |  |
|  |          |  | greenthread |  |  |  |
|  |          |  |_____________|  |  |  |
|  |          |   _____________   |  |  |
|  |          |  | greenthread |  |  |  |
|  |          |  |_____________|  |  |  |
|  |          |                   |  |  |
|  |          |        ...        |  |  |
|  |          |___________________|  |  |
|  |                                 |  |
|  |_________________________________|  |
|                                       |
|   _________________________________   |
|  | python thread                   |  |
|  |_________________________________|  |
|   _________________________________   |
|  | python thread                   |  |
|  |_________________________________|  |
|                                       |
|                 ...                   |
|_______________________________________|

  绿色线程是线程内的概念,同一个线程内的绿色线程之间是顺序执行的,绿色线程之间想要实现同步,需要开发人员在阻塞的代码位置显式植入CPU让渡,此时hub接管进行调度,寻找同一个线程内另一个可调度的绿色线程。注意绿色线程是线程内的概念,不能跨线程同步。

eventlet基本API

一、孵化绿色线程

eventlet.spawn(func, *args, **kw)

  该函数创建一个使用参数 *args**kw 调用函数 func 的绿色线程,多次孵化绿色线程会并行地执行任务。该函数返回一个greenthread.GreenThread 对象,可以用来获取函数 func 的返回值。

  

eventlet.spawn_n(func, *args, **kw)

  作用类似于spawn(),只不过无法获取函数 func 执行完成时的返回值或抛出的异常。该函数的执行速度更快

  

eventlet.spawn_after(seconds, func, *args, **kw)

  作用同于spawn(),等价于 seconds 秒后执行spawn()。可以对该函数的返回值调用 GreenThread.cancel() 退出孵化和阻止调用函数 func 

二、控制绿色线程

eventlet.sleep(seconds=0)

  挂起当前的绿色线程,允许其他的绿色线程执行

  

class eventlet.GreenPool

  控制并发的绿色线程池,可以控制并发度,进而控制整个并发所消耗的内存容量,或限制代码某一部分的连接数等

  

class eventlet.GreenPile

  GreenPile 对象代表了工作块。该对象是一个可以向其中填充工作的迭代器,便于以后从其中读取结果

  

class eventlet.Queue

  便于执行单元之间进行数据交流的基本构件,用于绿色线程之间的通信,

  

class eventlet.Timeout

  可以向任何东西添加超时,在 timeout 秒后抛出异常 exception。当 exception 被忽视或为None时,Timeout 实例自身会被抛出。Timeout 实例是上下文管理器(context manager),因此可以在 with 语句中使用

三、补丁函数

eventlet.import_patched(modulename, *additional_modules, **kw_additional_modules)

  引入标准库模块绿化后的版本,这样后续代码以非阻塞的形式执行,所需要的参数就是目标模块的名称,具体可参考 Import Green

  

eventlet.monkey_patch(all=True, os=False, select=False, socket=False, thread=False, time=False)

  在全局中为指定的系统模块打补丁,补丁后的模块是“绿色线程友好的”,关键字参数指示哪些模块需要被打补丁,如果 all 是真,那么所有的模块会被打补丁而无视其他参数;否则才由具体模块对应的参数控制对指定模块的补丁。多数参数为与自己同名的模块打补丁,如os, time, select,但是 socket 参数为真时,如果 ssl 模块也存在,会同时补丁socket模块和ssl模块,类似的,thread参数为真时,会补丁thread, threading 和 Queue 模块。

  可以多次调用monkey_patch(),详见 Monkeypatching the Standard Library

四、网络应用

eventlet.connect(addr, family=2, bind=None)

  开启客户端套接字

  参数:

  • addr – 目标服务器的地址,对于 TCP 套接字,这该参数应该是一个 (host, port) 元组
  • family – 套接字族,可选,详见 socket 文档
  • bind – 绑定的本地地址,可选

  返回:

  连接后的“绿色” socket 对象

eventlet.listen(addr, family=2, backlog=50)

  创建套接字,可以用于 serve() 或一个定制的 accept() 循环。设置套接字的 SO_REUSEADDR 可以减少打扰。

  参数:

  • addr:要监听的地址,比如对于 TCP 协议的套接字,这是一个(host, port) 元组。
  • family:套接字族。
  • backlog:排队连接的最大个数,至少是1,上限由系统决定。

  返回:

  监听中的“绿色”套接字对象。

eventlet.wrap_ssl(sock, *a, **kw)

  将一个普通套接字转变为一个SSL套接字,与 ssl.wrap_socket() 的接口相同。可以使用 PyOpenSSL,但是在使用 PyOpenSSL 时会无视 cert_reqs 、ssl_version 、ca_certs 、do_handshake_on_connect 和suppress_ragged_eofs 等参数。

  建议使用创建模式来调用该方法,如: wrap_ssl(connect(addr))  或  wrap_ssl(listen(addr),server_side=True) 。这样不会出现“裸”套接字监听非SSL会话的意外。

  返回:

  “绿色” SSL 对象。

  

eventlet.serve(sock, handle, concurrency=1000)

  在给定的套接字上运行服务器,对于每一个到来的客户端连接,会在一个独立的绿色线程中调用参数 handle ,函数 handle 接受两个参数,一是客户端的socket对象,二是客户端地址:

def myhandle(client_sock, client_addr):
    print("client connected", client_addr)

eventlet.serve(eventlet.listen((‘127.0.0.1‘, 9999)), myhandle)

  函数 handle 返回时将会关闭客户端套接字

  serve() 会阻塞调用的绿色线程,直到服务器关闭才返回,如果需要绿色线程立即返回,可以为 serve() 孵化一个新的绿色线程

  任何 handle 抛出的没有捕获的异常都会被当做serve()抛出的异常,造成服务器的终止,因此需要弄清楚应用会抛出哪些异常。handle 的返回值会被忽视。

  抛出一个 StopServe 异常来妥善地结束server – that’s the only way to get the server() function to return rather than raise.

  参数 concurrency 控制并发度,是任意时刻处理请求的绿色线程的数量上限,当服务器达到该上限时,它不会接受新的连接,直到有现有的完成为止。

class eventlet.StopServe

  用于妥善退出 serve() 的异常类

时间: 2024-10-06 00:11:21

Python——eventlet的相关文章

Python——eventlet.hubs

Hub构成了 Eventlet 的事件循环,它分发 I/O 事件.调度 greenthread.Hub的存在使得协程被提升为 greenthreads. Eventlet 有多种hub的实现,所以在使用之前应该选择最适合自己系统的实现: epolls 要求 Python 2.6 或 python-epoll 包,同时只支持 Linux.这是最快的纯Python hub. poll 所有支持它的平台均可. selects 哪都能用. pyevent 基于libevent的后端,最快!默认是不被支持

Python——eventlet.backdoor

eventlet.backdoor 是正在运行中的进程内的 Pyhon 交互解释器. 该模块便于检测一个长期运行进程的运行状态,提供了一种可以不阻塞应用正常操作的 Pyhon 交互解释器,从而极大地方便了调试.性能调优或仅仅是了解事情是怎么运转的. 在应用中孵化一个协程,这个协程运行一个 backdoor_server ,这个 backdoor_server 中有一个处于监听状态的套接字: eventlet.spawn(backdoor.backdoor_server, eventlet.lis

Python——eventlet.event

该模块提供eventlet的事件支持,事件提供了跨 greenthread 的操作原语. 同一个事件对象既可以发出事件也可以接收(等待)事件,不同的协程共享这一个事件对象,就为不同协程之间基于事件的同步提供了可能. class eventlet.event.Event 该类型抽象了以下事件:任意数量的协程可以等待其他一个协程发出的某一个事件. 事件类似于一个只能容纳一个对象的队列,但是有以下两个方面的区别: 1. 调用 send() 绝不会取消对当前greenthread的调度: 2. send

Python——eventlet.wsgi

eventlet 的 wsgi 模块提供了一种启动事件驱动的WSGI服务器的简洁手段,可以将其作为某个应用的嵌入web服务器,或作为成熟的web服务器,一个这样的web服务器的例子就是 Spawning. 目录 一.Eventlet 的 WSGI 服务器 1. eventlet.wsgi.server() 2. eventlet.wsgi.format_data_time() 二.SSL 三.Post hooks 四.“100 continue”响应头 一.Eventlet 的 WSGI ser

Python——eventlet.greenpool

该模块提供对 greenthread 池的支持. greenthread 池提供了一定数量的备用 greenthread ,有效限制了孵化 greenthread 过多导致的内存不足,当池子中没有足够的空闲 greenthread 时,孵化过程被暂停,只有当先前工作中的 greenthread 完成当前工作,才能为下一个任务做孵化准备. 本模块包括两个类: 1. eventlet.greenpool.GreenPool 2. eventlet.greenpool.GreenPile 一. cla

Python——eventlet.greenthread

该模块实现 eventlet 中的 “绿色线程” 即协程. 相关的 greenlet 模块的介绍. 目录 一.模块级函数 sleep() spawn() 模块级函数 eventlet.greenthread.sleep(seconds=0) 在至少参数 seconds 秒后让出控制权,参数 seconds 可以是一个整数,也可是浮点型的.当参数 seconds 为0时,主动让出控制权,在执行长时间计算时这么做有助于让别的协程也得到执行.  eventlet.greenthread.spawn(f

Python——eventlet.websocket

使用该模块可以方便地创建 websocket 服务器,要创建一个websocket服务器,只需要将一个句柄函数用装饰器 WebSocketWSGI 装饰即可,然后这个函数就可以当做一个WSGI应用: from eventlet import wsgi, websocket import eventlet @websocket.WebSocketWSGI def hello_world(ws): ws.send("hello world") wsgi.server(eventlet.li

Python框架、库以及软件资源汇总

转自:http://developer.51cto.com/art/201507/483510.htm 很多来自世界各地的程序员不求回报的写代码为别人造轮子.贡献代码.开发框架.开放源代码使得分散在世界各地的程序员们都能够贡献他们的代码与创新. Python就是这样一门受到全世界各地开源社区支持的语言.Python可以用来开发各种小工具软件.web应用.科学计算.数据分析等等,Python拥有大量的流行框架,比如Django.使用Python框架时,可以根据自己的需求插入不同的模块,比如可以用S

Machine and Deep Learning with Python

Machine and Deep Learning with Python Education Tutorials and courses Supervised learning superstitions cheat sheet Introduction to Deep Learning with Python How to implement a neural network How to build and run your first deep learning network Neur