Event loop error in asyncio Lock when instantiated multiple times
我在初始化Locks和运行异步代码时遇到了一些奇怪的错误。 假设我们有一个类可以与受锁保护的某些资源一起使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import asyncio class C: def __init__(self): self.lock = asyncio.Lock() async def foo(self): async with self.lock: return 'foo' def async_foo(): c = C() asyncio.run(c.foo()) if __name__ == '__main__': async_foo() async_foo() |
运行时会引发错误。 它在
RuntimeError: There is no current event loop in thread 'MainThread'.
因此,在函数中复制
到底是怎么回事? 而我该如何修改此代码才能正常工作? 让我也澄清一下,实例是在
或者,
What is going on?
-
创建异步对象(
asyncio.Lock() )时,它将附加到当前事件循环,并且只能与它一起使用 - 主线程具有一些默认的当前事件循环(但是您创建的其他线程将没有默认的事件循环)
-
asyncio.run() 在内部创建新的事件循环,将其设置为当前并在完成后关闭
因此,您尝试将锁定与事件循环一起使用,而不是将其与创建时附加的事件循环一起使用。这会导致错误。
And how could I modify this code to work?
理想的解决方案如下:
1 2 3 4 5 6 7 8 9 | import asyncio async def main(): # all your code is here if __name__ =="__main__": asyncio.run(main()) |
这将确保创建的每个异步对象都附加到已创建的正确事件循环
运行事件循环(在
I'd like for it to be usable elsewhere too.
您可以在
Alternatively, can threading.Lock be used for async things also?
不,它用于处理线程,而asyncio通常在单个线程内操作协程。
It would have the added benefit of being thread-safe, which asyncio.Lock reportedly is not.
在
考虑阅读以下链接。可能有助于更好地理解情况:
- 为什么我们需要异步/线程
- 什么时候应该编写异步代码而不是同步代码?