Spec-Zone.ru › Python 3.9

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

Исходный код: 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 может использоваться для обеспечения исключительного доступа к общему ресурсу.

Предпочтительный способ использования Lock — оператор 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 о том, что произошло какое-то событие.

Объект Event управляет внутренней переменной, которая может быть установлена в истинное значение методом 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 может быть использован задачей для ожидания наступления какого-либо события, а затем для получения исключительного доступа к общему ресурсу.

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

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

Устарело начиная с версии 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(). После разбуждения Condition снова получает свою блокировку, и этот метод возвращает 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.9: Приобретение блокировки с помощью 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.9/library/asyncio-sync.html

Spec-Zone.ru

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