Python 异步 asyncio 如何使用?
tasks = [fetch(BASE_URL + page_url, callback=parse_body, title=title) for title, page_url in TITLE2URL.items()] loop.run_until_complete(asyncio.gather(*tasks[:500])) 这里是把 500 个事件注册到事件循环? 那 j 假如我有 2000 个呢?
还有
tasks = [asyncio.ensure_future(task(i)) for i in range(0,300)] loop.run_until_complete(asyncio.gather(*tasks))
tasks = [task(i) for i in range(0,300)] loop.run_until_complete(asyncio.wait(tasks))
这两个区别是啥
Python 异步 asyncio 如何使用?
run_unitl_complete() 需要传入一个 Future 对象,但传入的是一个协程的话,会自动封装成 Future 对象。
asycio.wait() 和 asyncio.gather() 两个函数都是协程并行时需要用的,本质上没有区别。
asyncio.wait() 参数类型是列表 List[async],asyncio.gather() 则是多个协程 (async_1, async_2, … async_n)
一般来说,使用协程有时候会有回调。
asyncio.wait() 获取运行结果:
dones, pendings = await asyncio.wati(tasks)
asyncio.gather() 获取运行结果:
results = await asysncio.gather(*tasks)
帖子标题:Python 异步 asyncio 如何使用?
核心就三步:定义协程、创建事件循环、运行任务。
- 定义协程:用
async def声明异步函数,在需要等待的地方用await。 - 创建事件循环:
asyncio.run()会自动处理。 - 运行任务:用
asyncio.create_task()并发执行多个协程。
看个完整例子:
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay) # 模拟耗时操作
print(what)
async def main():
print(f"开始时间: {time.strftime('%X')}")
# 顺序执行
await say_after(1, 'Hello')
await say_after(2, 'World')
print(f"顺序执行结束: {time.strftime('%X')}")
# 并发执行
task1 = asyncio.create_task(say_after(1, '并发'))
task2 = asyncio.create_task(say_after(2, '执行'))
await task1
await task2
print(f"并发执行结束: {time.strftime('%X')}")
# Python 3.7+ 推荐方式
asyncio.run(main())
关键点:
await只能在async def函数里用asyncio.sleep()是非阻塞的,time.sleep()会阻塞整个事件循环create_task()把协程包装成任务,让它们能并发运行
常见模式:
# 等待多个任务完成
await asyncio.gather(task1, task2, task3)
# 设置超时
try:
await asyncio.wait_for(some_task(), timeout=5.0)
except asyncio.TimeoutError:
print("超时了")
# 同时运行,取第一个完成的
done, pending = await asyncio.wait([task1, task2], return_when=asyncio.FIRST_COMPLETED)
一句话建议:先理解事件循环模型,再动手写代码。
asyncio.wait() 和 asyncio.gather() 接收多个协程,本身自己返回一个协程对象。
ensure_future() 只是把协程封装成 task, task 是 Future 的子类。
python 的协程一直搞不懂
Future 是独立于协程的,用于并行时处理协程对象的结果; Task 是事件循环的基本单位
gather 一般用来解决多协程 callback 问题,当所有协程结束,这个协程才会结束(并 callback ),等于打包成主协程
没理解错的话,你代码里的 task 只是协程对象,并非 Task 对象
当然使用 py 协程不用理解太多,烧脑,直接把协程丢给 run_until_complete,它会处理好封装问题。
并且 py 基于协程的库,正常使用,只需要 async 和 await 就能跑起来了
asyncio gather 比较简单:它总是会等所有协程运行完毕。
而 wait 支持设置一些参数:比如设置等待时间;它可以不等待所有协程都运行完。
一个 wait 的使用常见场景:你开了 3 个协程,它们分别用不同方法去做同一件事,你只需要它们其中一个完成就可以了,这时,你可以使用 wait。
我感觉你去看两个函数的文档应该就能搞清楚它们的区别。

