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 如何使用?

7 回复

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 如何使用?

核心就三步:定义协程、创建事件循环、运行任务。

  1. 定义协程:用 async def 声明异步函数,在需要等待的地方用 await
  2. 创建事件循环asyncio.run() 会自动处理。
  3. 运行任务:用 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。

我感觉你去看两个函数的文档应该就能搞清楚它们的区别。

回到顶部