Примитивы синхронизации¶
Исходный код: Lib/asyncio/locks.py
Примитивы синхронизации asyncio разработаны так, чтобы они были аналогичны
примитивам модуля threading с двумя важными предостережения:
- asyncio примитивы не являются потокобезопасной, поэтому их не следует используемый
для синхронизации потоков ОС (для этого используйте 
threading); - методы из этих примитивов синхронизации не принимают аргумент timeout;
используйте функцию 
asyncio.wait_for()для выполнения операций с таймаутами. 
asyncio имеет следующие основные примитивы синхронизации:
Блокировки¶
- 
class 
asyncio.Lock(*, loop=None)¶ Реализует блокировку mutex для asyncio задач. Не потокобезопасной.
Для обеспечения исключительного доступа к совместно используемому ресурсу можно asyncio используемый блокировку.
Предпочтительным способом использования блокировки является
async withоператор:lock = asyncio.Lock() # ... позже async with lock: # доступ к общему состоянию
Что эквивалентно:
lock = asyncio.Lock() # ... позже await lock.acquire() try: # доступ к общему состоянию finally: lock.release()
Deprecated since version 3.8, will be removed in version 3.10: Параметр loop.
- 
coroutine 
acquire()¶ Установить блокировку.
Этот метод ждет, пока блокировка не unlocked, наборы он к locked и возвращаетs
True.Когда в
acquire()блокируется более одного корутина, ожидающего разблокирования замка, в конечном счете продолжается только один корутин.Приобретение замка - это fair: корутин, который идет, будет первым корутином, который начал ждать на замке.
- 
release()¶ Отпустить блокировку.
После locked блокировки Установить ее в unlocked и возвращает.
Если блокировка unlocked, то поднимается
RuntimeError.
- 
locked()¶ Возвращает
True, если блокировка locked.
- 
coroutine 
 
Событие¶
- 
class 
asyncio.Event(*, loop=None)¶ Объект событий. Не потокобезопасной.
Событие asyncio может быть используемый для уведомления нескольких asyncio задач о том, что произошло какое-либо событие.
Объект Event управляет внутренним флагом, который может быть установлен в true с помощью метода
set()и сброшен в false с помощью методаclear(). Методwait()блокируется, пока для флага не будет установлено значение true. Первоначально флаг установлен в false.Deprecated since version 3.8, will be removed in version 3.10: Параметр loop.
Пример:
async def waiter(event): print('waiting for it ...') await event.wait() print('... got it!') async def main(): # Создайте объект Event. event = asyncio.Event() # Создать задачу, чтобы подождать, пока не будет установлено "событие2. waiter_task = asyncio.create_task(waiter(event)) # Спать в течение 1 секунды и установить событие. await asyncio.sleep(1) event.set() # Подождите, пока официант не закончит свою работу. await waiter_task asyncio.run(main())
- 
coroutine 
wait()¶ Дождаться завершения установки события.
Если событие установлено, немедленно вернуть
True. В противном случае блокируйте, пока другая задача не вызоветset().
- 
set()¶ Установить событие.
Все задачи, ожидающие задания события, будут немедленно пробуждены.
- 
clear()¶ Очистить (отменить) событие.
Задачи, ожидающие на
wait(), теперь будут блокироваться до тех пор, пока методset()не будет повторно вызван.
- 
is_set()¶ Возвращает
True, если событие установлено.
- 
coroutine 
 
Состояние¶
- 
class 
asyncio.Condition(lock=None, *, loop=None)¶ Объект условия. Не потокобезопасной.
Примитив условия asyncio может быть используемый задачей, чтобы дождаться события и получить монопольный доступ к общему ресурсу.
По существу, объект Condition объединяет функциональные возможности
EventиLock. Возможно наличие нескольких объектов Condition совместно использующих один Lock, что позволяет координировать монопольный доступ к совместно используемому ресурсу между различными задачами, интересующими определенные состояниеs этого совместно используемого ресурса.Необязательный аргумент lock должен быть объектом
LockилиNone. В последнем случае новый объект Lock создается автоматически.Deprecated since version 3.8, will be removed in version 3.10: Параметр loop.
Предпочтительным способом использования условия является
async withоператор:cond = asyncio.Condition() # ... позже async with cond: await cond.wait()
Что эквивалентно:
cond = asyncio.Condition() # ... позже await cond.acquire() try: await cond.wait() finally: cond.release()
- 
coroutine 
acquire()¶ Получить основную блокировку.
Этот метод ожидает unlocked базовой блокировки, устанавливает ее в locked и возвращает
True.
- 
notify(n=1)¶ Не более n задач (по умолчанию 1), ожидающих выполнения этого условия. Если задачи не ожидаются, метод не выполняется.
блокировка должен быть получен до вызова этого метод и разблокирован вскоре после этого. При вызове с блокировкой unlocked возникает
RuntimeErrorошибка.
- 
locked()¶ Возвращает
True, будет ли получена соответствующая блокировка.
- 
notify_all()¶ Пробуждение всех задач, ожидающих выполнения этого условия.
Этот метод действует как
notify(), но просыпает все ожидающие задания.Блокировка должен быть получен до вызова этого метод и разблокирован вскоре после этого. При вызове с блокировкой unlocked возникает
RuntimeErrorошибка.
- 
release()¶ Разблокируйте основной блокировка.
При вызове при разблокированной блокировке возникает
RuntimeError.
- 
coroutine 
wait()¶ Жать, пока не зарегистрировано.
Если вызывающая задача не получила блокировку при вызове этого метод, возникает
RuntimeError.Этот метод освобождает основную блокировку, а затем блокирует ее до тех пор, пока она не будет пробуждена
notify()илиnotify_all()вызовом. После пробуждения условие вновь приобретает свой блокировка и это метод возвращаетsTrue.
- 
coroutine 
wait_for(predicate)¶ Додаться true predicate.
predicate должен быть вызываемым, результат которого будет интерпретироваться как логическое значение. Конечное значение является возвращает значением.
- 
coroutine 
 
Семафор¶
- 
class 
asyncio.Semaphore(value=1, *, loop=None)¶ Объект семафора. Не потокобезопасной.
Семафор управляет внутренним счетчиком, который уменьшается при каждом
acquire()вызове и увеличивается при каждомrelease()вызове. Счетчик никогда не может быть ниже нуля; когдаacquire()обнаруживает, что оно равно нулю, он блокируется, ожидая, пока какая-то задача не вызоветrelease().Необязательный аргумент value дает начальное значение для внутреннего счетчика (
1по умолчанию). Если заданное значение меньше0возникаетValueError.Deprecated since version 3.8, will be removed in version 3.10: Параметр loop.
Предпочтительным способом использования семафора является
async withоператор:sem = asyncio.Semaphore(10) # ... later async with sem: # работа с разделяемым ресурсом
Что эквивалентно:
sem = asyncio.Semaphore(10) # ... позже await sem.acquire() try: # работа с разделяемым ресурсом finally: sem.release()
- 
coroutine 
acquire()¶ Установка семафора.
Если внутренний счетчик больше нуля, уменьшите его на один и возвращает
Trueнемедленно. Если оно равно нулю, дождитесь вызоваrelease()и возвращаетTrue.
- 
locked()¶ Возвращает
True, если семафор не может быть получен немедленно.
- 
release()¶ Освобождение семафора, увеличив внутренний счетчик на единицу. Может пробудить задачу, ожидающую получения семафора.
В отличие от
BoundedSemaphore,Semaphoreпозволяет совершать большеrelease()вызовов, чемacquire().
- 
coroutine 
 
BoundedSemaphore¶
- 
class 
asyncio.BoundedSemaphore(value=1, *, loop=None)¶ Ограниченный семафорный объект. Не потокобезопасной.
Ограниченный семафор - версия
Semaphore, поднимающаяValueErrorвrelease(), если она увеличивает внутренний счетчик выше начального value.Deprecated since version 3.8, will be removed in version 3.10: Параметр loop.
Не рекомендуется, начиная с версии 3.7: Использование блокировки, используя await lock или yield from lock и/или with
оператор (with await lock, with (yield from lock)) запрещено. Используйте async with lock
вместо этого.
