Python Glossary English

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Сообщить о неточности