遇到的异步问题

事例1:

@app.post("/predictfunc")
async def predictfunc(item: Item):
    # 使用asyncio.to_thread()在单独的线程中运行predict_in_thread
    result = await asyncio.to_thread(predictfunc_main, item)
    return result

事例2:

@app.post("/remove_watermark_folder/")
async def remove_watermark_folder(folder_paths: FolderPaths):
    Path(folder_paths.output).mkdir(parents=True, exist_ok=True)
    tasks = []
    for filename in Path(folder_paths.input).iterdir():
            if filename.is_file() and filename.suffix.lower() in ['.jpg', '.png', '.jpeg']:
                input_path = filename
                pic_name=Path(input_path).name
                if len(str(input_path))>0:
                    task = asyncio.create_task(remove_watermark(input_path, folder_paths.output+pic_name))
                    tasks.append(task)
                    
    await asyncio.gather(*tasks)
    return {"message": "Watermarks removed and images saved successfully."}


问题:

这两种异步有什么区别

事例1:使用asyncio.to_thread

目的

  • 当你的异步函数中需要调用一个阻塞的、不支持异步的同步函数时(比如某些需要CPU密集型计算的任务或库不支持异步IO的情况),asyncio.to_thread是一个非常有用的工具。它允许你将这个同步函数在单独的线程中运行,而不会阻塞主事件循环。

特点

  • predictfunc函数接收一个Item对象作为参数,并使用asyncio.to_thread来调用predictfunc_main函数,这个函数可能是同步的且计算量较大。
  • 使用await等待asyncio.to_thread的结果,这意味着主函数会暂停执行,直到predictfunc_main函数在另一个线程中完成执行。

事例2:使用asyncio.create_taskasyncio.gather

目的

  • 当你的异步函数中需要并行处理多个异步任务时,可以使用asyncio.create_task来创建任务,并使用asyncio.gather来等待所有任务完成。这特别适用于IO密集型任务,如文件读写、网络请求等。

特点

  • remove_watermark_folder函数遍历一个文件夹中的文件,对符合条件的图片文件(如jpg、png、jpeg格式)并行执行去水印操作。
  • 对于每个符合条件的文件,使用asyncio.create_task创建一个去水印的任务(假设remove_watermark是一个异步函数),并将这些任务添加到tasks列表中。
  • 使用await asyncio.gather(*tasks)等待所有去水印任务完成。asyncio.gather会返回一个包含所有任务结果的元组,但在这个例子中,我们并没有直接使用这个结果,而是直接返回了一个表示成功的消息。

总结

  • 事例1适用于需要在异步函数中调用同步函数,且该函数执行时间较长或计算量较大的情况。
  • 事例2适用于需要并行处理多个异步任务,特别是IO密集型任务的情况。

两种写法都利用了Python的异步编程特性来提高程序的效率和响应性,但适用的场景和解决的问题不同。


线程池方式实现异步:

在fastapi中实现异步_fastapi 异步-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值