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

为何我的async函数陷入无限循环?基于asyncio的数据收发问题

问题分析

你当前的代码有两个核心问题:

  • fetcher无暂停点:fetcher里是纯无限循环,没有任何await操作,会一直占用事件循环,导致其他任务(比如sender唤醒后的逻辑)无法得到执行机会,看起来程序陷入抓取的无限循环。
  • 重复创建任务:main的循环每次都会新建sender和fetcher任务,旧的fetcher任务不会停止,最终导致大量重复的抓取任务同时运行,进一步加剧事件循环阻塞。
解决方案

利用asyncio的任务机制,让fetcher作为长期运行的后台任务持续抓取,sender周期性执行发送+冷却逻辑,两者共享事件循环,冷却期间fetcher自然会继续运行,无需全局变量。

修改后的代码:

import asyncio

data = []

async def fetcher():
    while True:
        # 模拟持续抓取数据的逻辑
        print("正在抓取数据...")
        data.append("新抓取的数据")
        # 必须加await让出事件循环,否则会阻塞所有任务
        # 这里根据实际抓取频率调整sleep时长,比如0.1秒抓一次
        await asyncio.sleep(0.1)

async def sender():
    while True:
        if data:
            # 模拟发送数据:取出所有积累的数据
            to_send = data.copy()
            data.clear()
            print(f"发送数据:{to_send}")
        # 发送后冷却10秒,期间事件循环会切换到fetcher继续抓取
        await asyncio.sleep(10)

async def main():
    # 启动fetcher作为后台任务,持续运行
    asyncio.create_task(fetcher())
    # 启动sender任务,await它让程序保持运行
    await sender()

asyncio.run(main())
关键说明
  • fetcher的await点:await asyncio.sleep(0.1)让事件循环有机会切换到其他任务,避免阻塞。如果你的实际抓取逻辑是异步IO操作(比如异步请求),本身就有await,就不需要额外加sleep。
  • 任务的生命周期:fetcher只启动一次,作为后台任务持续抓取;sender自己循环执行发送和冷却,两者共享事件循环,冷却期间fetcher会自动继续运行。
  • 数据同步:示例中用列表data存储抓取的数据,asyncio同一事件循环内的任务共享内存,只要不是多线程/多进程场景,无需额外锁(异步IO场景下,列表的append/clear操作是线程安全的)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:25:22