为什么 Python 异步编程里,一个简单的阻塞函数就能让整个服务“瘫痪”?答案其实很直接:因为 asyncio 的事件循环是单线程的,它没有分身术。一旦某个协程里跑了一个同步阻塞操作,整条流水线就会卡死,所有协程都得干等着。

asyncio 事件循环根本不能并行执行 CPU 或同步 I/O

事件循环的工作方式就是轮询加回调,调度协程切换,但从来不创建新线程。这意味着,一旦你在 async 函数里放了个 time.sleep()requests.get()open().read(),或者任何没有适配异步的库,控制权就彻底交出去了——没有回调、没有切换、没有“让出”,直到那个阻塞调用返回为止。

常见误用:以为加了 async/await 就自动异步了

这其实只是语法糖,不改变底层行为。比如下面这段代码,看起来是异步函数,但依然会阻塞:

async def bad_fetch():
    import requests
    return requests.get("https://httpbin.org/delay/3").json()  # ❌ 同步阻塞

它被标记为 async,但内部调用的是纯同步函数。事件循环照常启动这个协程,然后卡在 requests.get 上,动弹不得。

阻塞导致的连锁反应:超时失效、任务堆积、资源泄漏

一个协程阻塞,不仅自己卡住,还会拖垮所有依赖它的逻辑:

真正难察觉的点不是“哪里写了阻塞”,而是“哪里漏掉了异步适配”。比如日志写入用了 logging.info()(同步),配置加载用了 json.load(open(...))(同步),甚至第三方 SDK 内部偷偷调了 subprocess.run()(同步)。这些地方不会报错,但会在高并发下突然集体变慢。

本文转载于:https://www.php.cn/faq/2819747.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。