Примитивы синхронизации
Блокировки:
Семафоры:
API asyncio lock был разработан, чтобы быть похожим на классы модуля threading (Lock, Event, Condition, Semaphore, BoundedSemaphore), но он не имеет параметра timeout. Функция asyncio.wait_for() может использоваться для отмены задачи по истечении времени.
1. Блокировки
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.Значение не возвращается.
-
1.2. Событие
-
class asyncio.Event(*, loop=None) -
Реализация события, асинхронный эквивалент
threading.Event.Класс, реализующий объекты событий. Событие управляет флагом, который может быть установлен в значение true с помощью метода
set()и сброшен до false с помощью методаclear(). Методwait()блокируется до тех пор, пока флаг не станет true. Флаг изначально false.Этот класс не потокобезопасен.
-
clear() -
Сбрасывает внутренний флаг в значение false. В дальнейшем сопрограммы, вызывающие
wait(), будут заблокированы до тех пор, пока не будет вызваноset(), чтобы снова установить внутренний флаг в значение true.
-
is_set() -
Возвращает
Trueтолько в том случае, если внутренний флаг равен true.
-
set() -
Установить внутренний флаг в значение true. Все сопрограммы, ожидающие, пока он станет true, разбуживаются. Сопрограммы, вызывающие
wait(), как только флаг станет true, не будут блокироваться.
-
coroutine wait() -
Блокируется до тех пор, пока внутренний флаг не станет true.
Если внутренний флаг true при входе, немедленно вернуть
True. В противном случае, заблокироваться до тех пор, пока другая сопрограмма не вызоветset()для установки флага в значение true, а затем вернутьTrue.Этот метод является сопрограммой.
-
1.3. Условие
-
class asyncio.Condition(lock=None, *, loop=None) -
Реализация объекта Condition, асинхронный аналог
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) -
Ожидать, пока предикат не станет истинным.
Предикат должен быть вызываемой функцией, результат которой будет интерпретироваться как булево значение. Конечное значение предиката является возвращаемым значением.
Этот метод является сопроцессом.
-
2. Семафоры
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() -
Освободить семафор, увеличив внутренний счетчик на единицу. Если он был равен нулю при входе, и другой сопроцесс ожидает, пока он не станет больше нуля, разбудить этот сопроцесс.
-
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.5/library/asyncio-sync.html