Содержание страницы
18.5.7. Примитивы синхронизации¶Synchronization primitives
Исходный код: Lib/asyncio/locks.py
Блокировки:
Семафоры:
API блокировок asyncio было разработано так, чтобы быть близким к классам модуля threading
(Lock, Event,
Condition, Semaphore,
BoundedSemaphore), но у него нет параметра тайм-аут. Функция
asyncio.wait_for() может использоваться для отмены задачи по тайм-ауту.
18.5.7.1. Блокировки¶Locks
18.5.7.1.1. Блокировка¶Lock
-
class
asyncio.Lock(*, loop=None)¶ Объекты примитивных блокировок.
Примитивная блокировка – это примитив синхронизации, который не принадлежит конкретной корутине, когда заблокирован. Примитивная блокировка находится в одном из двух состояний: «locked» или «unlocked».
Она создаётся в разблокированном состоянии. У неё есть два основных метода:
acquire()иrelease(). Когда состояние разблокировано, acquire() изменяет состояние на заблокированное и возвращается немедленно. Когда состояние заблокировано, acquire() блокируется до тех пор, пока вызов release() в другой корутине не изменит его на разблокированное, затем вызов acquire() сбрасывает его в заблокированное и возвращается. Метод release() следует вызывать только в заблокированном состоянии; он изменяет состояние на разблокированное и возвращается немедленно. При попытке освободить разблокированную блокировку будет возбуждено исключениеRuntimeError.Когда несколько корутин заблокированы в acquire() в ожидании перехода состояния в разблокированное, только одна корутина продолжает работу, когда вызов release() сбрасывает состояние в разблокированное; обрабатывается первая корутина, заблокированная в acquire().
acquire()является корутиной и должна вызываться сyield from.Блокировки также поддерживают протокол менеджера контекста.
(yield from lock)следует использовать в качестве выражения менеджера контекста.This class is не является потокобезопасным.
Использование:
lock = Lock() ... yield from lock try: ... finally: lock.release()
Использование менеджера контекста:
lock = Lock() ... with (yield from lock): ...
Объекты блокировки можно проверить на состояние блокировки:
if not lock.locked(): yield from lock else: # блокировка получена ...
-
locked()¶ Возвращает
True, если блокировка захвачена.
-
coroutine
acquire()¶ Захватить блокировку.
Этот метод блокируется до тех пор, пока блокировка не будет разблокирована, затем устанавливает её в заблокированное состояние и возвращает
True.Этот метод является корутиной.
-
release()¶ Освободить блокировку.
Когда блокировка заблокирована, сбросить её в разблокированное состояние и вернуться. Если какие-либо другие корутины заблокированы в ожидании разблокировки блокировки, позволить ровно одной из них продолжить.
При вызове на не заблокированной блокировке возбуждается исключение
RuntimeError.Возвращаемое значение отсутствует.
-
18.5.7.1.2. Event¶
-
class
asyncio.Event(*, loop=None)¶ Реализация Event, асинхронный эквивалент
threading.Event.Класс, реализующий объекты событий. Событие управляет флагом, который может быть установлен в true с помощью метода
set()и сброшен в false с помощью методаclear(). Методwait()блокируется до тех пор, пока флаг не станет true. Изначально флаг установлен в false.This class is не является потокобезопасным.
-
clear()¶ Сбросить внутренний флаг в false. После этого корутины, вызывающие
wait(), будут блокироваться до тех пор, пока не будет вызванset()для повторной установки внутреннего флага в true.
-
is_set()¶ Возвращает
Trueтогда и только тогда, когда внутренний флаг равен true.
-
set()¶ Установить внутренний флаг в true. Все корутины, ожидающие его перехода в true, пробуждаются. Корутины, вызывающие
wait()после того, как флаг станет true, не будут блокироваться вообще.
-
coroutine
wait()¶ Блокироваться до тех пор, пока внутренний флаг не станет true.
Если внутренний флаг уже true при входе, немедленно вернуть
True. В противном случае блокироваться до тех пор, пока другая корутина не вызоветset(), чтобы установить флаг в true, затем вернутьTrue.Этот метод является корутиной.
-
18.5.7.1.3. Condition¶
-
class
asyncio.Condition(lock=None, *, loop=None)¶ Реализация Condition, асинхронный эквивалент
threading.Condition.Этот класс реализует объекты переменных условия. Переменная условия позволяет одной или нескольким корутинам ожидать, пока они не будут уведомлены другой корутиной.
Если аргумент блокировка задан и не равен
None, он должен быть объектомLock, и используется в качестве нижележащей блокировки. В противном случае создаётся новый объектLock, который используется в качестве нижележащей блокировки.This class is не является потокобезопасным.
-
coroutine
acquire()¶ Захватывает базовую блокировку.
Этот метод блокирует выполнение до тех пор, пока блокировка не будет разблокирована, затем устанавливает её в заблокированное состояние и возвращает
True.Этот метод является корутиной.
-
notify(n=1)¶ По умолчанию пробуждает одну корутину, ожидающую на этом условии, если такая есть. Если вызывающая корутина не захватила блокировку на момент вызова этого метода, возбуждается
RuntimeError.Этот метод пробуждает не более n корутин, ожидающих переменную условия; он ничего не делает, если никакие корутины не ожидают.
-
locked()¶ Возвращает
True, если базовая блокировка захвачена.
-
notify_all()¶ Пробуждает все корутины, ожидающие на этом условии. Этот метод действует как
notify(), но пробуждает все ожидающие корутины вместо одной. Если вызывающая корутина не захватила блокировку на момент вызова этого метода, возбуждаетсяRuntimeError.
-
release()¶ Освобождает базовую блокировку.
Когда блокировка заблокирована, сбросить её в разблокированное состояние и вернуться. Если какие-либо другие корутины заблокированы в ожидании разблокировки блокировки, разрешить ровно одной из них продолжить выполнение.
При вызове на не заблокированной блокировке возбуждается исключение
RuntimeError.Возвращаемое значение отсутствует.
-
coroutine
wait()¶ Ожидает уведомления.
Если вызывающая корутина не захватила блокировку на момент вызова этого метода, возбуждается
RuntimeError.Этот метод освобождает нижележащую блокировку, а затем блокирует выполнение до тех пор, пока он не будет пробуждён вызовом
notify()илиnotify_all()для той же переменной условия в другой корутине. После пробуждения он повторно захватывает блокировку и возвращаетTrue.Этот метод является корутиной.
-
coroutine
18.5.7.2. Семафоры¶Semaphores
18.5.7.2.1. Семафор¶Semaphore
-
class
asyncio.Semaphore(value=1, *, loop=None)¶ Реализация семафора.
Семафор управляет внутренним счётчиком, который уменьшается при каждом вызове
acquire()и увеличивается при каждом вызовеrelease(). Счётчик никогда не может опуститься ниже нуля; когдаacquire()обнаруживает, что он равен нулю, он блокирует выполнение, ожидая, пока какая-либо другая корутина вызоветrelease().Семафоры также поддерживают протокол управления контекстом.
Необязательный аргумент задаёт начальное значение внутреннего счётчика; по умолчанию он равен
1. Если указанное значение меньше0, возбуждаетсяValueError.This class is не является потокобезопасным.
-
coroutine
acquire()¶ Захватывает семафор.
Если внутренний счётчик больше нуля на входе, уменьшить его на единицу и немедленно вернуть
True. Если он равен нулю на входе, заблокировать выполнение, ожидая, пока какая-либо другая корутина вызоветrelease(), чтобы сделать его больше чем0, а затем вернутьTrue.Этот метод является корутиной.
-
locked()¶ Возвращает
True, если семафор не может быть захвачен немедленно.
-
release()¶ Освободить семафор, увеличивая внутренний счётчик на единицу. Если он был равен нулю на входе и другая корутина ожидает, пока он снова станет больше нуля, пробудить эту корутину.
-
coroutine
18.5.7.2.2. BoundedSemaphore¶
-
class
asyncio.BoundedSemaphore(value=1, *, loop=None)¶ Реализация ограниченного семафора. Наследуется от
Semaphore.Это возбуждает
ValueErrorвrelease(), если при этом значение превысило бы начальное значение.