Python
轻量级组件
协程
- 应用场景
- 耗时操作
- 原理
- 利用生成器(yield)
代码示例:
from greenlet import greenlet
from time import sleep
def foo():
for i in range(5):
print('foo:' + str(i))
P02.switch()
sleep(0.3)
def bar():
for i in range(5):
print('bar:' + str(i))
P01.switch()
sleep(0.3)
if __name__ == '__main__':
# switch功能类似yield + next,且不会因为生成超过任务本身的生成次数而导致的报错(先断点再生成下一次,阻塞函数)
P01 = greenlet(foo) # 创建协程对象
P02 = greenlet(bar)
P01.switch() # 主进程也被断点了(下方的代码不会执行)
'''
foo:0
bar:0
foo:1
bar:1
foo:2
bar:2
foo:3
bar:3
foo:4
bar:4
'''
gevent和monkey
- gevent
- greenlet的升级版(不用手动加switch)
- monkey
- 替换time.sleep,让gevent感觉到阻塞以达到切换
代码示例:
import time
import gevent
from gevent import monkey
monkey.patch_all() # 任何情况下一般必须置顶(在加载函数前替换,以防兼容性问题,特别是requests)
def foo():
for i in range(5):
print('foo:' + str(i))
time.sleep(0.3)
def bar():
for i in range(5):
print('bar:' + str(i))
time.sleep(0.3)
if __name__ == '__main__':
P01 = gevent.spawn(foo) # 创建协程对象及执行任务(当同时运行两个以上的协程对象任务时,根据是否在阻塞状态来实行交替运行)
P02 = gevent.spawn(bar)
P01.join() # 库本身原因,需要主进程让步
P02.join() # 可用gevent.joinall([P01,P02]) 代替(实参为可迭代对象)
'''
foo:0
bar:0
foo:1
bar:1
foo:2
bar:2
foo:3
bar:3
foo:4
bar:4
'''