Python 3.4+Асинхронное программированиепонятие
asyncio.Lock
синхронизация
Асинхронный мьютекс: пока одна задача держит замок, остальные ждут на async with, не блокируя цикл событий.
Синтаксис
lock = asyncio.Lock()
async with lock: ...
Замок нужен только там, где между проверкой и изменением общего состояния есть await: без await задачи не переключаются, и гонки нет. threading.Lock в корутине останавливает весь цикл, а asyncio.Lock — нет, но он не потокобезопасен. Замок не реентерабельный: повторный async with lock в той же задаче ждёт сам себя вечно. Захватывают его только через async with — обычный with lock даст TypeError.
Примеры
import asyncio
counter = 0
async def add(lock):
global counter
async with lock:
value = counter
await asyncio.sleep(0.01) # переключение здесь — без замка вышла бы гонка
counter = value + 1
async def main():
lock = asyncio.Lock()
await asyncio.gather(*(add(lock) for _ in range(5)))
print(counter) # → 5
asyncio.run(main())
# Python 3.11+
import asyncio
async def main():
lock = asyncio.Lock()
try:
with lock:
pass
except TypeError:
print('нужен async with') # → нужен async with
await asyncio.sleep(0.01)
asyncio.run(main())
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности