python runtime_error ai_generated true

RuntimeError: <asyncio.locks.Semaphore object at 0x...> is bound to a different event loop

ID: python/asyncio-semaphore-bound-to-different-event-loop

Also available as: JSON · Markdown · 中文
80%Fix Rate
86%Confidence
0Evidence
2024-09-11First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
3.8 active — — —
3.9 active — — —
3.10 active — — —
3.11 active — — —
3.12 active — — —

Root Cause

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.

generic

中文

在一个事件循环中创建的同步原语(Semaphore、Lock、Event)在另一个循环中使用,通常发生在跨 asyncio.run() 调用或跨线程复用模块级原语时。

Workarounds

  1. 92% success
    async def main():
        sem = asyncio.Semaphore(10)  # created inside running loop
        await asyncio.gather(*(worker(sem) for _ in range(100)))
    
    asyncio.run(main())
  2. 85% success
    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

Dead Ends

Common approaches that don't work:

  1. 90% fail

    Touching private attributes breaks invariants and usually still fails on the next acquire.

  2. 85% fail

    The primitive is unusable in the new loop; the exception recurs on every call.