1.协程
协程不是计算机提供的,它是程序员创造的。
协程-Co_routine,也可以称之为微线程,是一种用户态内的上下文切换技术,简而言之,其实就是通过一个线程实现代码块相互切换执行。
实现协程的几种方法:
-
greenlet,早期模块
-
yield关键字
-
asyncio装饰器(python3.4及其之后)
-
async、await关键字(python3.5及其之后)【推荐】
1.1 greenlet实现协程
pip3 install greenlet
from greenlet import greenlet def func1(): print(1) # step1: output 1 gr2.switch() # step3: switch to function func2 print(2) # step6: output 2 gr2.switch() # step7: 切换到func2函数,从上一次执行的位置继续向后执行 def func2(): print(3) # step4: output 3 gr1.switch() # step3: 切换到func1函数,从上一次执行的位置继续向后执行 print(4) # step6: output 4 gr1 = greenlet(func1) gr2 = greenlet(func2) gr1.switch() # step1: 去执行func1函数
1.2 yield关键字
def func1(): yield 1 yield from func2() yield 2 def func2(): yield 3 yield 4 f1 = func1() for item in f1: print(item)
1.3 asyncio
在python3.4及其之后的版本支持
import asyncio @asyncio.corountine def func1(): print(1) yield from asyncio.sleep(2) # 遇到io耗时操作,自动化切换到tasks中的其他任务 print(2) @asyncio.corountine def func2(): print(3) yield from asyncio.sleep(2) # 遇到io耗时操作,自动化切换到tasks中的其他任务 print(4) tasks = [ asyncio.ensure_future(func1()), asyncio.ensure_future(func2()) ] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks))
注意:遇到io阻塞的时候会自动切换,此时线程并没有闲着,一直在执行任务。
1.4 async & await 关键字
在python3.5及其以后版本
import asyncio async def func1(): print(1) await asyncio.sleep(2) # 遇到io耗时操作,自动化切换到tasks中的其他任务 print(2) async def func2(): print(3) await asyncio.sleep(2) # 遇到io耗时操作,自动化切换到tasks中的其他任务 print(4) tasks = [ asyncio.ensure_future(func1()), asyncio.ensure_future(func2()) ] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks))
2.协程的意义
充分的利用线程,不让线程出现阻塞从而浪费硬件资源,同时耗费更少的时间去完成任务。
3.异步编程
3.1 事件循环
一个死循环,去检测并执行某些代码7
# 伪代码: 任务列表 = [任务1, 任务2, 任务3, ...] while True: 可执行的任务列表, 已完成的任务列表 = 去任务列表中检查所有的任务,将‘可执行’和‘已完成’的任务返回 for 就绪任务 in 可执行任务列表: 执行已就绪的任务 for 已完成的任务 in 已完成的任务列表: 在任务列表中移除 已完成任务 如果 任务列表中的任务都已完成,则终止循环
import asyncio # 去生成或获取一个时间循环 loop = asyncio.get_event_loop() # 将任务放到'任务列表' loop.run_until_complete(任务)
3.2 快速上手
首先了解2个定义:
协程函数——定义函数的时候async def 函数名
协程对象——执行协程函数()得到的协程对象
import asyncio async de