协程库 gevent
2018-02-23 本文已影响0人
领悟悟悟
gevent,它是一个并发网络库。它的协程是基于greenlet的,并基于libev实现快速事件循环(Linux上是epoll,FreeBSD上是kqueue,Mac OS X上是select),协程阻塞时会自动调度(前提是打猴子补丁)
def demo_00():
import time
import gevent
#from gevent import monkey
#monkey.patch_all()
'''
也可以用gevent中提供的sleep函数替代time.sleep
一般推荐使用猴子补丁
'''
def func(a,b):
print(a,b)
time.sleep(3) # 标准库time.sleep是阻塞式的
f1 = gevent.spawn(func, 1,2)
f2 = gevent.spawn(func,3,4)
print(f1.started)
print(f2.started)
f1.join() # 此时是f1执行完毕才执行f2 >> 1 2 休眠 3 4 休眠
f2.join() # 去掉注释 f1休眠期间会打印 3,4
协程的执行方法.join/.start
join是阻塞式执行。 start是非阻塞式的即父协程结束,程序结束
def demo_01():
import gevent
def func():
print('协程休眠')
gevent.sleep(3)
print('休眠结束')
f1 = gevent.spawn(func)
f1.start()
time.sleep(1)
-
”gevent.joinall()”方法会等待所有传入的greenlet协程运行结束后再退出, 这个方法可以接受一个”timeout”参数来设置超时时间,单位是秒。等待时间超过还未结束便不会继续等待。
-
greenlet一个协程运行完后,必须显式切换,不然会返回其父协程。而在gevent中,一个协程运行完后,它会自动调度那些未完成的协程。
def demo_02():
import gevent
def test1():
print(12)
gevent.sleep(0)
print(34)
def test2():
print(56)
gevent.sleep(0)
print(78)
jobs = [gevent.spawn(test1),gevent.spawn(test2)]
gevent.joinall(jobs,timeout=5)
print([job.exception for job in jobs])
协程函数的执行状态,返回值与异常
协程状态有已启动和已停止,分别可以用协程对象的”started”属性和”ready()”方法来判断。对于已停止的协程,可以用”successful()”方法来判断其是否成功运行且没抛异常。如果协程执行完有返回值,可以通过”value”属性来获取。另外,greenlet协程运行过程中发生的异常是不会被抛出到协程外的,因此需要用协程对象的”exception”属性来获取协程中的异常。
def demo_03():
import gevent
def win():
return 'You win!'
def fail():
raise Exception('You failed!')
winner = gevent.spawn(win)
loser = gevent.spawn(fail)
print(winner.started) # True
print(loser.started ) # True
# 在Greenlet中发生的异常,不会被抛到Greenlet外面。
# 控制台会打出Stacktrace,但程序不会停止
try:
gevent.joinall([winner, loser])
except Exception as e:
# 这段永远不会被执行
print('This will never be reached')
print(winner.ready() ) # True
print(loser.ready() ) # True
print(winner.value) # 'You win!'
print(loser.value) # None
print(winner.successful() ) # True
print(loser.successful() ) # False
# 这里可以通过raise loser.exception 或 loser.get()
# 来将协程中的异常抛出
print(loser.exception)
参考:
百度
廖雪峰 gevent
Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)
gevent:轻松异步 I/O
基于协程的Python网络库gevent介绍