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

为何我的Python aiohttp请求代码无法异步运行?

解决aiohttp循环请求阻塞的问题

你的代码看似用了异步框架,但实际是串行执行的,所以每次迭代都会阻塞。原因是在for循环里,每一次都要等待await resp.text()执行完成后才会进入下一次循环,完全没发挥异步的并发优势,和同步代码没区别。

修复方案1:用asyncio.gather实现并发请求

先把单次请求封装成独立的异步函数,再批量创建任务并发执行:

import asyncio
import aiohttp

async def predict_image(session, image):
    image_bytes = pil_to_bytes(image)
    async with session.post('http://localhost:8080/predictions/resnet50', data=image_bytes) as resp:
        return await resp.text()

async def main():
    async with aiohttp.ClientSession() as session:
        # 为每个图片创建异步任务
        tasks = [predict_image(session, image) for image, target in dataset_val]
        # 并发执行所有任务并获取结果
        results = await asyncio.gather(*tasks)
        
        # 遍历结果输出
        for i, result in enumerate(results):
            print(result)
            print(i, flush=True, end='\r')

asyncio.run(main())

修复方案2:用信号量控制并发数(避免压垮API)

如果数据集很大,一次性发起所有请求可能会给API服务造成压力,这时可以用asyncio.Semaphore限制最大并发数:

import asyncio
import aiohttp

async def predict_image(session, semaphore, image):
    async with semaphore:  # 控制并发数
        image_bytes = pil_to_bytes(image)
        async with session.post('http://localhost:8080/predictions/resnet50', data=image_bytes) as resp:
            return await resp.text()

async def main():
    max_concurrent = 10  # 设置最大并发请求数
    semaphore = asyncio.Semaphore(max_concurrent)
    
    async with aiohttp.ClientSession() as session:
        tasks = [predict_image(session, semaphore, image) for image, target in dataset_val]
        results = await asyncio.gather(*tasks)
        
        for i, result in enumerate(results):
            print(result)
            print(i, flush=True, end='\r')

asyncio.run(main())

这两种写法都会让请求同时发起,大幅减少整体耗时,解决循环阻塞的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 18:48:24