Примитивы синхронизации
Исходный код: Lib/asyncio/locks.py
Блокировки:
Семафоры:
API-интерфейс блокировок asyncio разработан, чтобы быть похожим на классы модуля threading (Lock, Event, Condition, Semaphore, BoundedSemaphore), но в нём нет параметра timeout. Функция asyncio.wait_for() может быть использована для отмены задачи по истечении времени.
18.5.7.1. Блокировки
18.5.7.1.1. Блокировка
-
class asyncio.Lock(*, loop=None) -
Объекты примитивных блокировок.
Примитивная блокировка — это примитив синхронизации, который не принадлежит конкретному сопроцессу при блокировке. Примитивная блокировка находится в одном из двух состояний: ‘заблокирована’ или ‘не заблокирована’.
Она создаётся в состоянии ‘не заблокирована’. У неё есть два основных метода:
acquire()иrelease(). Когда состояние — ‘не заблокирована’, acquire() изменяет состояние на ‘заблокирована’ и возвращает значение немедленно. Когда состояние — ‘заблокирована’, acquire() блокируется до тех пор, пока вызов release() в другом сопроцессе не изменит его на ‘не заблокирована’, затем вызов acquire() устанавливает его обратно в ‘заблокирована’ и возвращает значение. Метод release() должен вызываться только в состоянии ‘заблокирована’; он изменяет состояние на ‘не заблокирована’ и возвращает значение немедленно. Если попытка освободить разблокированную блокировку, будет возбуждено исключениеRuntimeError.Когда более одного сопроцесса заблокированы в acquire() в ожидании изменения состояния на ‘не заблокирована’, только один сопроцесс продолжает выполнение, когда вызов release() устанавливает состояние в ‘не заблокирована’; обрабатывается первый сопроцесс, который заблокирован в acquire().
acquire()— это сопроцесс и должен вызываться сyield from.Блокировки также поддерживают протокол управления контекстом.
(yield from lock)следует использовать как выражение менеджера контекста.Этот класс не потокобезопасен.
Использование:
lock = Lock() ... yield from lock try: ... finally: lock.release()Использование менеджера контекста:
lock = Lock() ... with (yield from lock): ...Объекты блокировки могут быть проверены на состояние блокировки:
if not lock.locked(): yield from lock else: # lock is acquired ...-
locked() -
Возвращает
True, если блокировка приобретена.
-
coroutine acquire() -
Приобрести блокировку.
Этот метод блокируется до тех пор, пока блокировка не разблокирована, затем устанавливает её в заблокированное состояние и возвращает
True.Этот метод является сопроцессом.
-
release() -
Освободить блокировку.
Если блокировка заблокирована, сбросить её в состояние разблокированной и вернуть. Если какие-либо другие сопроцессы заблокированы в ожидании разблокировки блокировки, позволить ровно одному из них продолжить выполнение.
Если вызвать на разблокированной блокировке, возбуждается
RuntimeError.Значение возврата отсутствует.
-
18.5.7.1.2. Событие
-
class asyncio.Event(*, loop=None) -
Реализация событий, асинхронный аналог
threading.Event.Класс, реализующий объекты событий. Событие управляет флагом, который может быть установлен в истинное значение с помощью метода
set()и сброшен до ложного значения с помощью методаclear(). Методwait()блокируется до тех пор, пока флаг не станет истинным. Флаг изначально ложный.Этот класс не потокобезопасен.
-
clear() -
Сбросить внутренний флаг в ложное значение. Впоследствии, сопроцессы, вызывающие
wait(), будут заблокированы до тех пор, пока методset()не вызывается снова, чтобы установить внутренний флаг в истинное значение.
-
is_set() -
Возвращает
Trueтогда и только тогда, когда внутренний флаг имеет истинное значение.
-
set() -
Установить внутренний флаг в истинное значение. Все сопроцессы, ожидающие, пока он не станет истинным, пробуждаются. Сопроцесс, вызывающий
wait(), после того, как флаг станет истинным, не будет блокироваться.
-
coroutine wait() -
Блокировать до тех пор, пока внутренний флаг не станет истинным.
Если внутренний флаг имеет истинное значение при входе, возвращается
Trueнемедленно. В противном случае блокируется до тех пор, пока другой сопроцесс не вызоветset()для установки флага в истинное значение, затем возвращаетсяTrue.Этот метод является сопроцессом.
-
18.5.7.1.3. Условие
-
class asyncio.Condition(lock=None, *, loop=None) -
Реализация объекта условия, асинхронный аналог
threading.Condition.Этот класс реализует объекты переменных условия. Переменная условия позволяет одному или нескольким сопроцессам ожидать уведомления от другого сопроцесса.
Если аргумент lock задан и не
None, он должен быть объектомLock, и он используется в качестве базового замка. В противном случае создается и используется новый объектLockв качестве базового замка.Этот класс не потокобезопасен.
-
coroutine acquire() -
Захват базового замка.
Этот метод блокируется до тех пор, пока замок не будет разблокирован, затем устанавливает его в заблокированное состояние и возвращает
True.Этот метод является сопроцессом.
-
notify(n=1) -
По умолчанию разбудит один сопроцесс, ожидающий этого условия, если таковой имеется. Если вызывающий сопроцесс не захватил замок при вызове этого метода, генерируется
RuntimeError.Этот метод разбудит не более n сопроцессов, ожидающих переменной условия; это бездействие, если нет ожидающих сопроцессов.
-
locked() -
Возвращает
Trueесли базовый замок захвачен.
-
notify_all() -
Разбудить все сопроцессы, ожидающие этого условия. Этот метод действует как
notify(), но разбуживает все ожидающие сопроцессы вместо одного. Если вызывающий сопроцесс не захватил замок при вызове этого метода, генерируетсяRuntimeError.
-
release() -
Освободить базовый замок.
Когда замок заблокирован, сбросить его в разблокированное состояние и вернуть значение. Если другие сопроцессы заблокированы, ожидая, пока замок станет разблокированным, разрешить продолжить ровно одному из них.
При вызове на разблокированном замке генерируется
RuntimeError.Значение не возвращается.
-
coroutine wait() -
Ожидать уведомления.
Если вызывающий сопроцесс не захватил замок при вызове этого метода, генерируется
RuntimeError.Этот метод освобождает базовый замок, а затем блокируется до пробуждения вызовом
notify()илиnotify_all()для той же переменной условия в другом сопроцессе. После пробуждения он снова захватывает замок и возвращаетTrue.Этот метод является сопроцессом.
-
coroutine wait_for(predicate) -
Ожидать, пока предикат не станет истинным.
Предикат должен быть вызываемым объектом, результат которого будет интерпретирован как логическое значение. Конечное значение предиката — это возвращаемое значение.
Этот метод является сопроцессом.
-
18.5.7.2. Семафоры
18.5.7.2.1. Семафор
-
class asyncio.Semaphore(value=1, *, loop=None) -
Реализация семафора.
Семафор управляет внутренней переменной, которая уменьшается при каждом вызове
acquire()и увеличивается при каждом вызовеrelease(). Переменная никогда не может стать меньше нуля; когдаacquire()обнаруживает, что она равна нулю, он блокируется, ожидая, пока другой сопроцесс не вызоветrelease().Семафоры также поддерживают протокол управления контекстом.
Необязательный аргумент задает начальное значение внутренней переменной; по умолчанию
1. Если заданное значение меньше0, возникаетValueError.Этот класс не потокобезопасен.
-
coroutine acquire() -
Захват семафора.
Если внутренняя переменная больше нуля при входе, уменьшите её на единицу и верните
Trueнемедленно. Если она равна нулю при входе, заблокируйтесь, ожидая, пока другой сопроцесс не вызоветrelease(), чтобы сделать её больше0, и затем вернитеTrue.Этот метод является сопроцессом.
-
locked() -
Возвращает
Trueесли семафор нельзя захватить немедленно.
-
release() -
Освободить семафор, увеличив внутреннюю переменную на единицу. Когда при входе она была равна нулю и другой сопроцесс ждёт, пока она станет больше нуля, разбудить этот сопроцесс.
-
18.5.7.2.2. Ограниченный семафор
-
class asyncio.BoundedSemaphore(value=1, *, loop=None) -
Реализация ограниченного семафора. Наследуется от
Semaphore.Это вызывает
ValueErrorвrelease(), если это увеличит значение выше начального значения.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/asyncio-sync.html