基于协程的异步编程(协程)-1
协程
协程不是计算机提供的,是程序员人为创造,也可以称为微线程
简而言之就是通过一个线程实现在代码块中互相切换。
协程的意义是什么?
在一个线程中如果遇到了io等待了,线程不在一直等着,利用空闲时间去干点别的事,充分利用线程。
Python中实现写成的几种方式
通过greenlet实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 1、通过greenlet实现携程(早期模块) # pip install greenlet from greenlet import greenlet def func1(): print(1) # 第二步 打印 1 gr2.switch() # 第三步 切换到func2函数 print(2) # 第六步 打印 2 gr2.switch() # 第七步 切换到func2函数 def func2(): print(3) # 第四步 打印 3 gr1.switch() # 第五步 切换到func1函数 print(4) # 第八步 打印4 gr1 = greenlet(func1) gr2 = greenlet(func2) gr1.switch() # 第一步:去执行func1函数 # 最终输出 1 3 2 4 |
通过yield关键字实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
def func3(): yield 1 yield from func4() # 通过yield from切换到func4 yield 2 def func4(): yield 3 yield 4 # 通过yield也实现了 一个线程在代码块之间相互切换,但是只是概念上相符合,实际没啥用。 f3 = func3() for f in f3: print(f) |
通过asyncio模块实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 3、asyncio 官方推荐协程模块 (python3.4及之后版本可以使用,自带模块) import asyncio @asyncio.coroutine def func5(): print(1) yield from asyncio.sleep(2) # 遇到IO操作 主动切换到其他任务中 模拟遇到IO print(2) @asyncio.coroutine def func6(): print(3) yield from asyncio.sleep(2) # 遇到IO操作 主动切换到其他任务中 模拟遇到IO print(4) tasks = [ asyncio.ensure_future(func5()), asyncio.ensure_future(func6()) ] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks)) |
python3.5以后 可以通过async & await关键字使用 (推荐)
本质和上面3中的使用相同,只是去掉了装饰器和yield 换成了async 和 await
强悍之处在与,遇到io情况,主动切换,而不是像上面需要手动切换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import asyncio async def func7(): print('a') await asyncio.sleep(2) # 遇到IO操作 主动切换到其他任务中 模拟遇到IO print('b') async def func8(): print('c') await asyncio.sleep(2) # 遇到IO操作 主动切换到其他任务中 模拟遇到IO print('d') tasks = [ asyncio.ensure_future(func7()), asyncio.ensure_future(func8()) ] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks)) |
什么是事件循环
1 2 3 4 5 6 7 8 9 10 11 |
任务列表 = [任务1,任务2,任务3,....] while True: 可执行的任务列表,已完成的任务列表 = 检查任务列表中任务的状态,返回可执行和已完成的任务 for 就绪任务 in 可执行的任务列表: 执行就绪任务 for 已完成任务 in 已完成任务列表: 任务列表中删除已完成列表 如果任务列表都完成了,则终止循环。 |
uvloop
asyncio默认事件循环的替代品。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# uvloop 是 asyncio的事件循环的替代品,要比默认的事件循环快,性能要更好。 # 使用起来也很简单,只需要安装注册替换下即可。 # pip3 install uvloop import uvloop import asyncio # 将默认的事件循环替换成uvloop asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) async def func(): print(1) await asyncio.sleep(2) print(2) return '返回值' task_list = [ func(), func() ] done, pending = asyncio.run(asyncio.wait(task_list, timeout=None)) print('done', done) print('pending', pending) |
未经允许不得转载:大师兄 » 基于协程的异步编程(协程)-1
评论已关闭