python
runtime_error
ai_generated
true
RuntimeError: <asyncio.locks.Semaphore object at 0x...> 绑定到了不同的事件循环
RuntimeError: <asyncio.locks.Semaphore object at 0x...> is bound to a different event loop
ID: python/asyncio-semaphore-bound-to-different-event-loop
80%修复率
86%置信度
0证据数
2024-09-11首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 3.8 | active | — | — | — |
| 3.9 | active | — | — | — |
| 3.10 | active | — | — | — |
| 3.11 | active | — | — | — |
| 3.12 | active | — | — | — |
根因分析
在一个事件循环中创建的同步原语(Semaphore、Lock、Event)在另一个循环中使用,通常发生在跨 asyncio.run() 调用或跨线程复用模块级原语时。
English
A synchronization primitive (Semaphore, Lock, Event) created in one event loop is used in another, typically when a module-level primitive is reused across asyncio.run() calls or threads.
解决方案
-
92% 成功率
async def main(): sem = asyncio.Semaphore(10) # created inside running loop await asyncio.gather(*(worker(sem) for _ in range(100))) asyncio.run(main()) -
85% 成功率
loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) sem = asyncio.Semaphore(10) # created once loop.run_until_complete(main(sem)) # subsequent runs reuse the same loop
无效尝试
常见但无效的做法:
-
90% 失败
Touching private attributes breaks invariants and usually still fails on the next acquire.
-
85% 失败
The primitive is unusable in the new loop; the exception recurs on every call.