1、gevent 介绍
小编介绍
gevent是通过协成封装实现的,实现起来让代码更加简洁,用于IO密集型的场景,如果
例如大规模网络并发请求的时候,可以使用Gevent,例如我们经常使用的requests 是Python 程序员经常拿来发出网络请求的模块,他是同步的,为了发出大量并发异步请求,我们可以使用grequest ,他是requests的作者,使用requests模块 结合gevent 构造而成,我们可以直接使用不必重新造轮子。
那另外说一点:而对应的计算密集型的需求,应当采用传统的多线程、多进程方案,就不适合使用gevent。
官方介绍
是一个基于libev的并发库。它为各种并发和网络相关任务提供了一个干净的 API。目标是为您提供使用 gevent 所需的工具,帮助您解决现有的并发问题并立即开始编写异步应用程序。
gevent 中使用的主要模式是Greenlet,这是一个作为 C 扩展模块提供给 Python 的轻量级协程。Greenlets 都在主程序的 OS 进程内运行,但都是协作调度的。这不同于由操作系统提供的任何真正的并行构造 multiprocessing或threading库,它们执行由操作系统调度并且真正并行的自旋进程和 POSIX 线程。
并发的核心思想是将一个更大的任务分解为一组子任务,这些子任务被安排同时或异步运行,而不是一次或同步运行一个。两个子任务之间的切换称为上下文切换。
gevent 中的上下文切换是通过yielding完成的。在这个例子中,我们有两个上下文,它们通过调用 gevent.sleep().
2、Gevent案例:
案例1:
import gevent
def foo():
print('foo start')
gevent.sleep(3)
print('foo end')
def bar():
print('bar start')
gevent.sleep(2)
print('bar end')
def eat():
print('eat start')
gevent.sleep(1)
print('eat end ')
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
gevent.spawn(eat)
])
#输出结果
'''
foo start
eat start
bar start
eat end
bar end
foo end
Process finished with exit code 0
'''
通过输出结果可以得出结论,函数执行的顺序默认会按照joinall配置的执行,当函数遇到sleep阻塞的时候,就会执行其他函数,直到最后执行最堵塞的函数完毕。
案例2:
当我们将它用于可以协同安排的网络和IO绑定功能时,gevent的真正力量就来了。
Gevent已经处理了所有细节,以确保您的网络库尽可能隐式地产生greenlet上下文。
我不能强调这是一个强大的习语。但也许一个例子将说明。
在这种情况下,该select()函数通常是一个阻塞调用,它会轮询各种文件描述符。
import time
import gevent
from gevent import select
start = time.time()
tic = lambda: 'at %1.1f seconds' % (time.time() - start)
def gr1():
# Busy waits for a second, but we don't want to stick around...
print('Started Polling: %s' % tic())
select.select([], [], [], 2)
print('Ended Polling: %s' % tic())
def gr2():
# Busy waits for a second, but we don't want to stick around...
print('Started Polling: %s' % tic())
select.select([], [], [], 2)
print('Ended Polling: %s' % tic())
def gr3():
print("Hey lets do some stuff while the greenlets poll, %s" % tic())
gevent.sleep(1)
gevent.joinall([
gevent.spawn(gr1),
gevent.spawn(gr2),
gevent.spawn(gr3),
])
'''
运行结果
Started Polling: at 0.0 seconds
Started Polling: at 0.0 seconds
Hey lets do some stuff while the greenlets poll, at 0.0 seconds
Ended Polling: at 2.0 seconds
Ended Polling: at 2.0 seconds
'''