eventlet

wsgi  server

#!/usr/bin/python

import eventlet

from eventlet importwsgi

 

def hello_world(env,start_response):

    start_response('200 OK', [('Content-Type','text/plain')])

    return ['Hello, World!\r\n']

 

wsgi.server(eventlet.listen(('',8090)), hello_world)

 

 

测试:wget http://0.0.0.0:8090  -O - -q;  echo ""    work well

 

 

绿色线程:协程

#!/usr/bin/python

 

import eventlet

from greenlet importgreenlet

 

def test1():

    print 12

    gr2.switch()

    print 34

 

def test2():

    print 56

    gr1.switch()

    print 78

 

gr1 =greenlet(test1)

gr2 =greenlet(test2)

#gr1.switch()

 

def fun():

    print("----fun---")

    eventlet.sleep(1)

    print("----fun-end--")

   

   

def fun2():

    print("----fun2---")

    eventlet.sleep(5)

    #time.sleep(10) #协程不会切换

    print("----fun2-end--")

    

gt = eventlet.spawn(fun)    #创建一个协程,那么什么时候开始调度执行呢? 等到出现可以切换的IO操作就开始执行,可切换的IO操作包括绿化过的IO 协程的waiteventlet.sleep, eventlet.event.Event().wait()

gt2 =eventlet.spawn(fun2)

gt.wait()  #协程的执行函数fun退出后,wait返回, wait也是一个IO操作,所以开始切换到其他协程

gt2.wait()  # fun2退出后,wait才返回,实际使用时需要定义一个永远不退出协程( eventlet.sleep 无限长时间,或者用 eventlet.event.Event().wait()),由此协程进行wait

 

 

 

Hub构成了 Eventlet 的事件循环,它分发 I/O 事件、调度 greenthreadHub的存在使得协程被提升为 greenthreads

Eventlet 有多种hub的实现,所以在使用之前应该选择最适合自己系统的实现:

来自 <http://www.cnblogs.com/Security-Darren/p/4178686.html>

Hub是怎么工作的

hub 有一个主 greenletMAINLOOP。当运行中的协程需要进行 I/O 操作时,它会在 hub 中注册一个 listener(这样hub就知道什么时候唤醒它),然后切换到 MAINLOOP (通过 get_hub().switch())。如果有其他准备运行的协程, MAINLOOP 会切换到他们,当他们完成执行或需要 I/O 时,又会将控制权切换给 MAINLOOP。以这样的方式,MAINLOOP 确保了每一个协程在自己有事要完成的时候都能够得到调度。

MAINLOOP只在第一次I/O发生时执行,而且它不是 __main__ 所运行在的那个 greenlet这种延迟运行的方式解释了为什么不需要显式地调用 dispatch() 方法,也就是说代码不需要重构就可以开始使用 Eventlet

 

 

Python——eventlet.event

>>> from eventlet import event
>>>importeventlet
>>>evt =event.Event()
>>>defwaiter():
...     print
('about towait')
...     result
=evt.wait()
...     print
('waited for{0}'.format(result))
>>>_ =eventlet.spawn(waiter)  #创建协程
>>> eventlet.sleep(0)  #睡眠,开始切换到其他协程
about to wait
>>>evt.send('a')  #不会马上唤醒其他协程
>>>eventlet.sleep(0)
waited for
a

 

来自 <http://www.cnblogs.com/Security-Darren/p/4168116.html>

 

 

 

绿色线程组:协程组

 

#!/usr/bin/python

 

importeventlet

fromeventlet import wsgi

 

defhello_world(env, start_response):

    start_response('200 OK', [('Content-Type','text/plain')])

    return ['good, Hello, World!\r\n']

 

def fun():

    wsgi.server(eventlet.listen(('', 8090)),hello_world)

 

#wsgi.server(eventlet.listen(('', 8090)), hello_world) #进程不会退出

 

pool =eventlet.GreenPool(100)

 

pool.spawn_n(fun)  #fun还未得到调度

 

#如果接下来没有其他代码,则进程退出,因为fun是一个还没启动的协程(还未得到调度)

pool.waitall() #开始启动协程,fun开始调度,也可以用 eventlet.event.Event().wait()启动。本质上waitall是一个绿化的操作,注册wait事件,并切换到MAINLOOP

可以定义多个协程组,只要某一个协程组调用waitall(),则所有的协程组都开始调度

 

#!/usr/bin/python

 

importeventlet

fromeventlet import wsgi

importtime

fromeventlet import event

 

eventlet.monkey_patch()

 

pool =eventlet.GreenPool(100)

pool2= eventlet.GreenPool(100)

    

deffun1():

    print("fun1---begin")

    eventlet.sleep(2)

    print("fun1---end")

   

deffun2():

    print("fun2---begin")

    eventlet.sleep(2)

    pool2.spawn(fun1)  # pool.spawn(fun1)

    print("fun2---after spawnfun1")   

   time.sleep(10)  #time.sleephook了,实际执行的是eventlet.sleep

    print("fun2---end")

 

deflog_exceptions(gt):

        print("log_exceptions")       

 

defrun_forever():

    while True:

        print("run_forever")

        eventlet.sleep(1)

 

pool.spawn(run_forever)

pool2.spawn(fun2)

 

pool.waitall()

#evt =event.Event()

#evt.wait()

 

 

 

#!/usr/bin/python

 

import eventlet

from eventlet importwsgi

 

def hello_world(env,start_response):

    start_response('200 OK', [('Content-Type','text/plain')])

    return ['good, Hello, World!\r\n']

 

   

def fun():

    print("server---begin")

    wsgi.server(eventlet.listen(('', 8090)),hello_world)

   

def fun2():

    print("fun2---begin")

    eventlet.sleep(20)

    print("fun2---end")

   

#wsgi.server(eventlet.listen(('',8090)), hello_world)

pool =eventlet.GreenPool(100)

pool.spawn_n(fun2)

pool.spawn_n(fun)

 

pool.waitall()  #先执行fun2fun2 sleep之后再执行fun,所有协程执行完毕之后,waitall就返回,程序结束。当然wsgi.serve是不会结束的(内部有while不断循环)

### 关于 `asyncio` 和 `eventlet` 的比较 #### 定义与核心概念 `asyncio` 是 Python 标准库中的模块,用于编写异步程序[^1]。它提供了一种基于事件循环的方式来进行并发操作,允许开发者通过协程来实现非阻塞的 IO 操作。 `eventlet` 则是一个第三方库,专注于轻量级绿色线程(green threads),并提供了更高层次的抽象来简化网络编程[^3]。它的设计目标是让开发人员能够轻松处理大量并发连接而无需担心底层复杂性。 --- #### 实现方式 `asyncio` 使用的是显式的协程机制,依赖于 `await`/`async` 关键字以及事件循环驱动的任务调度模型。这种模式下,程序员需要手动定义哪些部分应该被挂起等待完成,并且这些挂起的操作通常涉及文件读写或者网络请求等耗时任务。 相比之下,`eventlet` 基于 greenlets 技术实现了隐式的上下文切换功能。这意味着当某个函数调用了可能长时间运行的方法时(比如 HTTP 请求),框架会自动将其转换成非阻塞形式继续执行其他逻辑直到该方法返回结果为止——这一切对于使用者来说几乎是透明的过程[^2]. --- #### 性能表现 就性能而言,在高负载情况下如果只是单纯追求吞吐率的话,则可能会发现采用纯单一线程架构加上传统同步风格编码再加上一些优化技巧之后仍然可以达到相当不错的效率水平;然而一旦涉及到复杂的业务流程控制或者是频繁交互型应用场景(例如WebSocket服务端),那么利用像`asyncio`这样的工具包往往可以获得更好的扩展性和响应速度[^1]^. 另一方面,尽管由于存在全局解释器锁(GIL)的影响使得纯粹依靠多线程并不能充分利用现代CPU多核特性从而提升计算密集型工作的效能[GIL相关内容见引述][^2],但对于I/O绑定的工作负载而言(event loop本质上也是围绕着这一类问题构建起来的技术方案之一),无论是选用哪种具体的解决方案都能够显著改善整体系统的资源利用率情况. --- #### 开发体验 从易用性的角度来看,初学者或许会觉得直接上手学习如何正确运用好`asyncio`相对更具挑战一点因为它引入了一些新的语法结构和理念;但是随着熟悉程度加深以后就可以享受到更加灵活可控的好处. 至于`eventlet`,因为其背后隐藏了许多细节所以刚开始接触的时候感觉比较简单直观容易快速搭建原型出来不过长期维护大型项目时则需要注意潜在的风险点比如难以调试等问题[^3]. --- #### 使用场景建议 - **推荐使用 `asyncio`:** - 当应用程序主要关注高性能 I/O 处理并且愿意接受较陡峭的学习曲线时。 - 对未来可移植性强有需求的情况下,考虑到它是标准库的一部分意味着跨平台兼容性较好。 - **适合选择 `eventlet`:** - 如果希望尽快启动小型到中型规模的服务端应用而又不想花太多时间研究内部工作机制的话。 - 需要支持大量的短生命周期客户端连接同时保持较低内存占用比例的情形之下。 ```python import asyncio # Example of an async function using asyncio async def fetch_data(): await asyncio.sleep(1) return {"data": "value"} loop = asyncio.get_event_loop() result = loop.run_until_complete(fetch_data()) print(result) # Eventlet example would look simpler but less explicit about where yielding happens from eventlet import greenthread def blocking_call(): greenthread.sleep(1) return {"data": "value"} blocking_result = blocking_call() # Automatically yields control during sleep print(blocking_result) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值