网站制作学习网Python→正文:python async await
字体:

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 有修改

forasp.cn

·上一篇:FastApi debug reload模式 >>    ·下一篇:python 的进程池和线程池 >>
推荐文章
最新文章