异步编程
1.事件循环
理解成一个死循环
伪代码
任务列表=[]
while True:
可执行的任务列表,已完成的任务列表=去任务列表中检查所有的任务,将可执行和已完成的任务返回
for 就绪任务 in 已就绪的任务列表:
执行已就绪的任务
for 已完成的任务 in 已完成的任务列表:
在任务列表中移除 已完成的任务
如果任务列表均已完成,则终止循环
import asyncio
#生成一个事件循环
loop=asyncio.get)event_loop()
#将任务放到任务列表
loop.run_until_complete(任务)
快速上手
协程函数: 定义函数的时候 async def 函数名
协程对象:执行协程函数得到的协程对象
async def func():
pass
result=func()
注意:执行协程函数创建协程对象,函数内部代码不会执行。
如果想要运行函数内部代码,必须要将协程对象交给事件循环来处理
async def func():
pass
result=func()
---------------------------
loop=asyncio.get)event_loop()
loop.run_until_complete(result)#常用
------------------------
asyncio.run(result)#py3.7之后的版本
await关键字
await + 可等待的对象 (协程对象,future,task对象)------io等待
li1:
import asyncio
async def func():
print()
response=await asyncio.sleep()
print()
asyncio.run(func())
li2:
import asyncio
async def o():
print("s")
response=await asyncio.sleep()
print("e")
async def func():
print("")
response=await o()
print("")
asyncio.run(func())
li3:一个协程函数可以有多个协程切换
import asyncio
async def o():
print("s")
response=await asyncio.sleep()
print("e")
async def func():
print("")
response=await o()
print("")
response=await o()
print("")
asyncio.run(func())
task对象
在事件循环中添加多个任务,task用于并发调度协程,通过asyncio.create_task(协程对象)的方式创建tsk对象,这样可以让协程加入事件循环中等待被调度执行,除了使用该函数还可以使用低层次的loop.create_task()或ensure_future()函数,不建议手动实例化task对象
li1:
import asyncio
async def o():
print("s")
response=await asyncio.sleep()
print("e")
async def func():
print("")
#创建task对象,将当前执行func函数任务添加到事件循环
task1=asyncio.create_task(o())
task2=asyncio.create_task(o())
print("")
ret1= await task1
ret2= await task2
asyncio.run(o())
li2:(常用)
import asyncio
async def o():
print("s")
response=await asyncio.sleep()
print("e")
async def func():
print("")
#创建task对象,将当前执行func函数任务添加到事件循环
task_list=[
asyncio.create_task(o()),
asyncio.create_task(o())
]
print("")
#done 任务列表中的返回值
done,pending=await asyncio.wait(task_list,timeout=2)#等待列表中的任务,最多等两秒,也可以是None
li3:
import asyncio
async def func():
print(1)
await asyncio.sleep(2)
print(2)
return ""
task_list=[
asyncio.create_task(o()),
asyncio.create_task(o())
#o(),
#o()
]
#done,pending=ascio.run(asyncio.wait(task_list))
s=ascio.run(asyncio.wait(task_list))
future对象
task继承future,task对象内部await结果的处理基于future来的
li1:
async def main():
#获取当前事件循环
loop=asyncio.get_running_loop()
#创建一个任务,这个任务什么也不干
fut=loop.create_future()
#等待任务最终结果,没有结果会一直等下去
await fut
asyncio.run(main())
li2:
import asyncio
async def set_after(fut):
await asyncio.sleep(2)
fut.set_result('666')
async def main():
#获取当前事件循环
loop=asyncio.get_running_loop()
#创建一个任务,这个任务什么也不干
fut=loop.create_future()
#等待任务最终结果,没有结果会一直等下去
await loop.create_task(set_after(fut))
#手动设置future对象结果就可以结束
data=await fut
print(data)
asyncio.run(main())
concurrent.future.Future对象
使用线程池,进程池实现异步操作时用到的对象。
以后写代码可能会存在交叉使用,
异步迭代器
异步上下文管理器
uvloop
是asyncio事件循环的替代方案。事件循环>asyncio的事件循环