You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用asyncio异步调用无返回值的耗时IO/绘图函数?

嘿,这就帮你把调用异步函数的事儿理清楚~

首先,你的doStuff函数已经用async def定义成异步函数了,但调用异步函数得依托asyncio的事件循环,不同Python版本的写法略有区别,我给你分情况说明:

1. Python 3.7+ 推荐写法:用asyncio.run()

这是Python 3.7之后官方推荐的最简方式,它会帮你自动创建、运行、关闭事件循环,不用手动处理那些繁琐的循环操作:

import asyncio
import matplotlib.pyplot as plt

async def doStuff(input_data):
    plt.figure()
    plt.plot(input_data)
    plt.savefig('foobar.pdf')
    plt.close()  # 记得关闭图形,避免内存占用过高

if __name__ == "__main__":
    # 示例输入数据
    test_input = [1, 3, 2, 5, 4]
    # 直接用asyncio.run调用异步函数
    asyncio.run(doStuff(test_input))

2. 旧版本Python(3.6及以下):手动管理事件循环

如果你的Python版本比较老,就得手动获取事件循环,然后让它运行到任务完成:

import asyncio
import matplotlib.pyplot as plt

async def doStuff(input_data):
    plt.figure()
    plt.plot(input_data)
    plt.savefig('foobar.pdf')
    plt.close()

if __name__ == "__main__":
    test_input = [1, 3, 2, 5, 4]
    # 获取事件循环
    loop = asyncio.get_event_loop()
    # 让循环运行直到doStuff完成
    loop.run_until_complete(doStuff(test_input))
    # 最后关闭循环
    loop.close()

重要补充:关于“真异步”的小提醒

这里得给你提个醒:你写的doStuff里的matplotlib绘图、保存操作其实都是同步阻塞的,单纯用async def包装它并不会让它真的异步执行(也就是说,如果同时调用多个这类函数,它们还是会串行运行)。

如果想让这类阻塞型的IO/绘图操作真正异步并行,你需要把这些同步任务放到线程池或者进程池里运行,比如用Python 3.9+的asyncio.to_thread(),或者旧版本的loop.run_in_executor():

import asyncio
import matplotlib.pyplot as plt
from concurrent.futures import ThreadPoolExecutor

# 先把同步操作单独写成一个普通函数
def sync_draw_and_save(input_data):
    plt.figure()
    plt.plot(input_data)
    plt.savefig(f'foobar_{input_data[0]}.pdf')  # 加个后缀区分不同文件
    plt.close()

# 异步函数里调用线程池执行同步任务
async def async_doStuff(input_data):
    await asyncio.to_thread(sync_draw_and_save, input_data)
    # 要是用Python 3.8及以下,就换成下面的写法:
    # loop = asyncio.get_running_loop()
    # await loop.run_in_executor(ThreadPoolExecutor(), sync_draw_and_save, input_data)

# 如果要同时运行多个任务,用asyncio.gather()
async def main():
    # 准备多组输入,同时生成多个文件
    tasks = [
        async_doStuff([1,2,3]),
        async_doStuff([4,5,6]),
        async_doStuff([7,8,9])
    ]
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(main())

这样就能真正实现多个绘图/保存任务的异步并行啦~

内容的提问来源于stack exchange,提问作者FooBar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:37:37