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 的进程池和线程池 >>
