Spec-Zone.ru › Python 3.8

Примитивы синхронизации

Исходный код: Lib/asyncio/locks.py

Примитивы синхронизации asyncio предназначены для сходства с примитивами модуля threading с двумя важными оговорками:

  • Примитивы asyncio не потокобезопасны, поэтому их не следует использовать для синхронизации потоков ОС (для этого используйте threading);
  • методы этих примитивов синхронизации не принимают аргумент timeout; используйте функцию asyncio.wait_for() для выполнения операций с таймаутами.

asyncio имеет следующие основные примитивы синхронизации:

  • Lock
  • Event
  • Condition
  • Semaphore
  • BoundedSemaphore

Блокировка

class asyncio.Lock(*, loop=None)

Реализует мьютекс-блокировку для задач asyncio. Не потокобезопасна.

Блокировка asyncio может использоваться для обеспечения эксклюзивного доступа к общим ресурсам.

Предпочтительный способ использования блокировки — оператор async with:

lock = asyncio.Lock()

# ... later
async with lock:
    # access shared state

что эквивалентно:

lock = asyncio.Lock()

# ... later
await lock.acquire()
try:
    # access shared state
finally:
    lock.release()

Устарело начиная с версии 3.8, будет удалено в версии 3.10: Параметр loop.

coroutine acquire()

Захватить блокировку.

Этот метод ожидает, пока блокировка не будет разблокирована, устанавливает её в заблокированное состояние и возвращает True.

Когда более одной корутины заблокированы в acquire() в ожидании разблокировки блокировки, только одна корутина в конечном итоге продолжает выполнение.

Получение блокировки честное: корутина, которая продолжит работу, будет первой корутиной, которая начала ожидание блокировки.

release()

Освободить блокировку.

Когда блокировка заблокирована, она сбрасывается в разблокированное состояние и возвращается значение.

Если блокировка разблокирована, генерируется исключение RuntimeError.

locked()

Возвращает True если блокировка заблокирована.

Событие

class asyncio.Event(*, loop=None)

Объект события. Не потокобезопасен.

Объект события asyncio может использоваться для уведомления нескольких задач asyncio о том, что произошло некоторое событие.

Объект события управляет внутренней меткой, которая может быть установлена в истинное значение с помощью метода set() и сброшена в ложное значение с помощью метода clear(). Метод wait() блокирует выполнение, пока метка не будет установлена в истинное значение. Изначально метка имеет значение ложь.

Устарело начиная с версии 3.8, будет удалено в версии 3.10: Параметр loop.

Пример:

async def waiter(event):
    print('waiting for it ...')
    await event.wait()
    print('... got it!')

async def main():
    # Create an Event object.
    event = asyncio.Event()

    # Spawn a Task to wait until 'event' is set.
    waiter_task = asyncio.create_task(waiter(event))

    # Sleep for 1 second and set the event.
    await asyncio.sleep(1)
    event.set()

    # Wait until the waiter task is finished.
    await waiter_task

asyncio.run(main())
coroutine wait()

Ожидать, пока событие не будет установлено.

Если событие установлено, вернуть True немедленно. В противном случае заблокировать выполнение до тех пор, пока другая задача не вызовет set().

set()

Установить событие.

Все задачи, ожидающие установки события, будут немедленно разбужены.

clear()

Сбросить (убрать установку) события.

Задачи, ожидающие события с помощью wait(), теперь будут блокироваться до тех пор, пока метод set() снова не будет вызван.

is_set()

Возвращает True если событие установлено.

Условие

class asyncio.Condition(lock=None, *, loop=None)

Объект условия. Не потокобезопасен.

Примитив условия asyncio может использоваться задачей для ожидания наступления некоторого события и последующего получения эксклюзивного доступа к общему ресурсу.

По сути, объект условия объединяет функциональность объекта Event и Lock. Можно иметь несколько объектов условия, использующих одну блокировку, что позволяет координировать эксклюзивный доступ к общему ресурсу между различными задачами, заинтересованными в определенных состояниях этого общего ресурса.

Необязательный аргумент lock должен быть объектом Lock или None. В последнем случае объект блокировки создаётся автоматически.

Устарело начиная с версии 3.8, будет удалено в версии 3.10: Параметр loop.

Предпочтительный способ использования условия — оператор async with:

cond = asyncio.Condition()

# ... later
async with cond:
    await cond.wait()

что эквивалентно:

cond = asyncio.Condition()

# ... later
await cond.acquire()
try:
    await cond.wait()
finally:
    cond.release()
coroutine acquire()

Захватить базовую блокировку.

Этот метод ожидает, пока базовая блокировка не будет разблокирована, устанавливает её в заблокированное состояние и возвращает True.

notify(n=1)

Разбудить не более n задач (по умолчанию 1), ожидающих этого условия. Метод ничего не делает, если задач нет.

Блокировка должна быть захвачена перед вызовом этого метода и освобождена вскоре после этого. Если вызвать с разблокированной блокировкой, возникает ошибка RuntimeError.

locked()

Возвращает True если базовая блокировка захвачена.

notify_all()

Разбудить все задачи, ожидающие этого условия.

Этот метод действует как notify(), но разбуживает все ожидающие задачи.

Блокировка должна быть захвачена перед вызовом этого метода и освобождена вскоре после этого. Если вызвать с разблокированной блокировкой, возникает ошибка RuntimeError.

release()

Освободить базовую блокировку.

Если вызвать на разблокированной блокировке, генерируется исключение RuntimeError.

coroutine wait()

Ожидать уведомления.

Если вызывающая задача не захватила блокировку, когда этот метод вызывается, возникает ошибка RuntimeError.

Этот метод освобождает базовую блокировку, а затем блокирует выполнение до тех пор, пока он не будет разбужен вызовом notify() или notify_all(). После пробуждения условие повторно захватывает свою блокировку, и этот метод возвращает True.

coroutine wait_for(predicate)

Ожидать, пока предикат не станет истинным.

Предикат должен быть вызываемым объектом, результат которого будет интерпретироваться как булево значение. Конечное значение — это возвращаемое значение.

END_OF_DOCUMENT_MARKER

Семафор

class asyncio.Semaphore(value=1, *, loop=None)

Объект семафора. Не потокобезопасен.

Семафор управляет внутренней счётчиком, который уменьшается при каждом вызове acquire() и увеличивается при каждом вызове release(). Счётчик никогда не может опуститься ниже нуля; когда acquire() обнаруживает, что он равен нулю, он блокируется, ожидая, пока какая-то задача не вызовет release().

Необязательный аргумент value задаёт начальное значение внутреннего счётчика (по умолчанию 1). Если заданное значение меньше 0, генерируется исключение ValueError.

Устаревшее с версии 3.8, будет удалено в версии 3.10: Параметр loop.

Предпочтительный способ использования семафора — оператор async with:

sem = asyncio.Semaphore(10)

# ... later
async with sem:
    # work with shared resource

что эквивалентно:

sem = asyncio.Semaphore(10)

# ... later
await sem.acquire()
try:
    # work with shared resource
finally:
    sem.release()
coroutine acquire()

Получить семафор.

Если внутренний счётчик больше нуля, уменьшить его на единицу и вернуть True немедленно. Если он равен нулю, подождать, пока не будет вызвано release(), и вернуть True.

locked()

Возвращает True если семафор не может быть получен немедленно.

release()

Освободить семафор, увеличив внутренний счётчик на единицу. Может разбудить задачу, ожидающую получения семафора.

В отличие от BoundedSemaphore, Semaphore позволяет делать больше release() вызовов, чем acquire() вызовов.

Ограниченный семафор

class asyncio.BoundedSemaphore(value=1, *, loop=None)

Объект ограниченного семафора. Не потокобезопасен.

Ограниченный семафор — это версия Semaphore, которая генерирует исключение ValueError в release(), если она увеличивает внутренний счётчик выше начального значения value.

Устаревшее с версии 3.8, будет удалено в версии 3.10: Параметр loop.

Устаревшее с версии 3.7: Получение блокировки с использованием await lock или yield from lock и/или оператора with (with await lock, with (yield from lock)) устарело. Используйте async with lock вместо этого.

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/library/asyncio-sync.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API