1.引言
python中asyncio是异步编程的代表,为什么会需要异步编程?当处理I/O密集型任务的时候,比如说查询数据库,文件操作,网络请求等等。同步方式会因为等待I/O操作而阻塞整个应用。asyncio的异步方案,相比较多线程,有效减少上下文切换的开销;相比较于多进程,资源消耗更少!是个不错的方案。
asyncio可以高效实现如下场景:
- web服务:同时处理大量客户端请求
- 爬虫:并行下载
- 实时数据处理:高效处理多个数据流
2.案例
2.1.核心概念三要素
2.1.1.协程
asyncio关键步骤:
- 通过async关键字定义协程函数(任务函数)
- 通过await关键字调用协程函数
- 通过asyncio.run方法启动执行
python
import asyncio
# 定义协程函数
async def say_hello(name):
# 模拟I/O等待
await asyncio.sleep(1)
print(f"Hello, {name}!")
# 运行协程
async def main():
await say_hello("小王")
await say_hello("老王")
# 运行
asyncio.run(main())

2.1.2.事件循环
python
import asyncio
# 定义协程函数
async def say_hello(name):
# 模拟I/O等待
await asyncio.sleep(1)
print(f"Hello, {name}!")
# 事件循环,通过事件循环执行任务
loop = asyncio.get_event_loop()
task = loop.create_task(say_hello("小王"))
loop.run_until_complete(task)
loop.close()

2.1.3.可等待对象
可等待对象有三类:
- 协程对象:直接通过await调用
- Task对象:并发执行多个协程
- Future对象:底层异步操作容器
2.2.实践案例
设计一个模拟定时任务进度显示案例:
python
import asyncio
# 定义协程函数:倒计时
async def countdown(number):
while number > 0:
print(f"剩余: {number}秒")
await asyncio.sleep(0.1)
number -= 1
print("倒计时结束!")
# 定义协程函数:计算进度
async def progress_bar(total):
for i in range(total+1):
percent = i/total*100
print(f"[{'#'*int(percent//2)}{' '*(50-int(percent//2))}] {percent:.1f}%")
await asyncio.sleep(0.1)
async def main():
await asyncio.gather(
countdown(10),
progress_bar(10)
)
# 运行主协程
asyncio.run(main())

2.3.线程,进程,asyncio选择
