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

Python异步函数致Jupyter Notebook内核崩溃问题求助

可能的原因及解决办法

1. asyncio.run 与 Jupyter 事件循环的冲突

Jupyter Notebook本身已经维护着一个asyncio事件循环,而asyncio.run()会创建全新的独立循环,再加上nest_asyncio.apply()修改了原有循环的嵌套规则,两种循环的状态容易发生冲突,最终导致内核崩溃。

解决办法:
直接在Jupyter单元格中await异步函数,无需调用asyncio.run()或手动获取循环执行。Jupyter支持在交互环境中直接执行异步代码:

# 移除 nest_asyncio.apply() 和 asyncio.run()
async def fetch_url(session, url):
    async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as response:
        return await response.text()
    
async def gather_fetched_urls(urls):
    async with aiohttp.ClientSession() as session: 
        tasks = [fetch_url(session, url) for url in urls]  # 无需 ensure_future,asyncio.gather 可直接接收协程
        results = await asyncio.gather(*tasks, return_exceptions=True)
        return results

URLs_list = ["你的API地址1", "你的API地址2"]
responses = await gather_fetched_urls(URLs_list)

2. 未处理的请求异常

如果某个API请求抛出异常(比如超时、连接失败、HTTP错误),asyncio.gather()默认会直接抛出异常,而Jupyter内核对未捕获的异步异常处理不够健壮,可能触发内核崩溃。

解决办法:
给asyncio.gather()添加return_exceptions=True参数,将异常作为结果返回,避免整个任务链崩溃;同时给请求添加超时时间,防止请求无限挂起:

async def fetch_url(session, url):
    try:
        async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as response:
            response.raise_for_status()  # 捕获HTTP错误(比如404、500)
            return await response.text()
    except Exception as e:
        return f"请求失败: {str(e)}"

3. nest_asyncio 的潜在副作用

nest_asyncio.apply()会修改asyncio的核心循环逻辑,允许嵌套运行事件循环,但这种修改可能和Jupyter的循环管理机制不兼容,尤其是在资源清理阶段(比如ClientSession关闭时),容易引发循环状态混乱。

解决办法:
只有在确实需要嵌套运行循环时才使用nest_asyncio,如果只是在Jupyter单元格中执行单次异步任务,完全不需要调用它。

4. 资源泄漏

如果请求数量过大,或者任务没有被正确回收,可能导致内存耗尽或文件句柄泄漏,最终让内核崩溃。

解决办法:

  • 控制并发请求数量:使用asyncio.Semaphore限制同时发起的请求数,避免一次性创建过多任务压垮系统:
async def gather_fetched_urls(urls):
    semaphore = asyncio.Semaphore(10)  # 限制最多10个并发请求
    
    async def bounded_fetch(url):
        async with semaphore:
            async with aiohttp.ClientSession() as session:
                return await fetch_url(session, url)
    
    tasks = [bounded_fetch(url) for url in urls]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    return results
  • 确保所有ClientSession都通过async with正确关闭,避免资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:45:16