Я сталкиваюсь с некоторыми странными ошибками при инициализации Locks и выполнении асинхронного кода. Предположим, у нас есть класс для использования с некоторым ресурсом, защищенным блокировкой.
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()
Это приводит к ошибке при запуске. Это происходит при инициализации блокировки в init
.
RuntimeError: В потоке 'MainThread' нет текущего события l oop.
Так что дублирование asyncio.run
вызов в функции не имеет этого эффекта. Кажется, что объект должен быть инициализирован несколько раз. Также недостаточно создать несколько блокировок в одном конструкторе. Так что, возможно, это как-то связано с состоянием циклов событий после вызова asyncio.run
.
Что происходит? И как я могу изменить этот код для работы? Позвольте мне также уточнить, что экземпляр создается за пределами функций asyncio.run
и asyn c по определенной причине. Я бы хотел, чтобы его можно было использовать и в других местах. Если это имеет значение.
В качестве альтернативы, можно ли threading.Lock
использовать также для асин c вещей? Дополнительным преимуществом было бы то, что он безопасен для потоков, что, как сообщается, asyncio.Lock
не является.