python async await
Python 2024/6/1 16:32:03 点击:不统计
http://%77%77%77%2E%66网站制作%6F学习网%72%61%73%70%2E%63%6E
学习理解下,python中的协程异步操作,它时通过async await实现。
1. 协程(异步)
充分利用线程cpu时间,提高效率。当线程中有需要等待其他资源时,让线程暂时转向处理线程内的其他任务或方法,当其他资源完成后,线程再回来继续执行当前内容。
2. 实现原理
(1)死循环事件检测
tasks = [task1,task2.....]
while(True):
# 检查各个任务状态
going_works = tasks中资源完毕的
done_works = tasks中完成的
for task in going_works:
执行就绪任务
for task in done_works:
移除完成任务
(2) python 中实现循环
import asyncio
loop = asyncio.get_event_loop() # 获取一个循环对象
loop.run_until_complete(任务) # 循环检查完成的任务。
(3)代码实现 async
定义协程函数
async def function_name():
pass
协程对象
function_obj = function_name()
通过循环执行,来实现协程对象代码执行。
python3.7以前,代码如下:
import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(function_obj)
python3.7 以及以后,代码如下
import asyncio
asyncio.run(function_obj)
3. await 对象 await 等待 一般 await+可以等待对象(协程对象,Future,Task对象IO)
(1) 协程对象
import asyncio
async def process():
asyncio.sleep(2)
print("ok")
async def function_name():
await process()
pass
asyncio.run(function_name())
(2)Taks 对象, 可以理解为多个独立任务并发,每个任务都是独立的互补干涉。
python3.7后,创建task对象
task_obj = asyncio.create_task(协程对象)
案例代码如下:
基础任务方法
async def function_name():
await asyncio.sleep(2)
pass
单独任务处理,如果有多个独立任务,它会顺序异步执行。
async def process():
task1 = asyncio.create_task(function_name())
task2 = asyncio.create_task(function_name())
result1 = await task1
result2 = await task2
print(result1, result2)
asyncio.run(process())
合并任务 方法
import asyncio
async def process():
print("start")
task_list = [
asyncio.create_task(function_name(),name="task_name1"),
asyncio.create_task(function_name(),name="task_name2")
]
# 循环检查完成的任务
done,pending = await asyncio.wait(task_list,timeout=None)
print(done)
asyncio.run(process())
如果将任务写到 外部
task_list=[
function_name(),
function_name()
]
done,pending = asyncio.run(asyncio.wait(task_list))
如果等待多个任务同时返回,则用gather,只有两个任务都完成才返回
async def main():
# 并发执行两个任务
result1, result2 = await asyncio.gather(function_name(), function_name())
print(result1)
print(result2)
# 运行主函数
asyncio.run(main())
(3) Future 对象,是task 的基类。
案例代码:
async def process():
loop = asyncio.get_event_loop() # 创建循环对象
fun = loop.create_future()
await fun
asyncio.run(process())
因为上面代码没有任何执行内容,只有一个循环,没有装填返回,则一直会await
task 会直接会有fun执行,而Future 添加任务。
添加任务后代码如下:
import asyncio
async def set_result(loop_fun):
await asyncio.sleep(2)
loop_fun.set_result("结束内容")
async def process():
loop = asyncio.get_event_loop()
loop_fun = loop.create_future()
await loop.create_task(set_result(loop_fun))
result_data = await loop_fun
print(result_data)
asyncio.run(process())
4. async 将非异步的请求转为异步请求
直接看案例
import asyncio
import requests # 同步网络请求函数
async def call_api(url):
loop = asyncio.get_event_loop()
loop_object = loop.run_in_executor(None,requests.get, url)
response = await loop_object
return response.content
api_list= [url1, url2,url3]
tasks = [call_api[url] for url in api_list] # 这里将call 转换为 异步函数
loop = asyncio.get_event_loop()
loop.run_until_complete( asyncio.wait(tasks) )
5. uvloop 事件循环 asyncio 的替代方案
uvloop 效率要比 asyncio 高。
安装扩展
pip install uvloop
代码替换 asyncio原始方法
import asyncio
import uvloop
# 下面更改 asyncio原始方法为uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
其余方法与原始asyncio 方法 一致。
6 案例 redis 操作
import asyncio
import aioredis
async def exec(addr,pwd):
print("init redis")
redis = await aioredis.create_redis(adr, password=pwd)
await redis.hmset_dict("car", key1=1,key2=2)
result = await redis.hgetall("car", encoding='utf-8')
print(result)
redis.close()
await redis.wait_close()
print("over")
asyncio.run( exec("redis addr", "redis pwd") )
如果是多个链接
task_list= [exec("redis addr", "redis pwd"),exec("redis addr", "redis pwd")]
asyncio.run(async.wait(task_list))
学习总结来源:https://www.bilibili.com/video/BV1NA411g7yf 有修改
学习总结来源:https://www.bilibili.com/video/BV1NA411g7yf 有修改
·上一篇:FastApi debug reload模式 >> ·下一篇:python 的进程池和线程池 >>