18.5.7. 同步原语¶
锁:
信号量:
asyncio lock API was designed to be close to classes of the threading
module (Lock
, Event
, Condition
, Semaphore
, BoundedSemaphore
), but it has no timeout parameter. asyncio.wait_for()
函数可用于在超时后取消任务。
18.5.7.1. Locks¶
18.5.7.1.1. Lock¶
- class
asyncio.
Lock
(*, loop=None)¶ 原语锁对象。
原语锁是同步原语,当锁定时不属于特定的协程。原始锁处于两种状态之一,“锁定”或“解锁”。
它是在解锁状态下创建的。它有两个基本方法,
acquire()
和release()
。当状态解锁时,acquire()将状态更改为锁定并立即返回。当状态被锁定时,acquire()阻塞直到对另一个协程中的release()的调用将其改变为解锁,然后acquire()调用将其重置为锁定并返回。release()方法只能在锁定状态下调用;它将状态更改为已解锁并立即返回。如果尝试释放已解锁的锁,将会引发RuntimeError
。当在acquire()中阻塞了多个协程等待状态转为解锁时,只有一个协程在release()调用将状态重置为未锁定时进行;正在处理在acquire()中被阻塞的第一协程。
acquire()
是协程,应使用yield from
调用。锁也支持上下文管理协议。
(产生 从 锁定)
应用作上下文管理器表达式。此类为not thread safe。
用法:
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
。
-
release
()¶ 释放锁。
当锁被锁定时,将其重置为解锁,然后返回。如果任何其他协程被阻止等待锁被解锁,则只允许其中一个继续。
当在未锁定的锁上调用时,会引发
RuntimeError
。没有返回值。
-
18.5.7.1.2. Event¶
- class
asyncio.
Event
(*, loop=None)¶ 事件实现,异步等效于
threading.Event
。实现事件对象的类。事件管理可以使用
set()
方法设置为true的标志,并使用clear()
方法将其复位为false。wait()
方法阻塞,直到标志为真。该标志最初为假。此类为not thread safe。
-
is_set
()¶ 当且仅当内部标志为真时返回
True
。
-
18.5.7.1.3. Condition¶
- class
asyncio.
Condition
(lock=None, *, loop=None)¶ 条件实现,异步等效于
threading.Condition
。这个类实现条件变量对象。条件变量允许一个或多个协程等待,直到它们被另一个协程通知。
如果给出了lock参数,而不是
None
,则它必须是Lock
对象,并且用作基础锁。否则,将创建一个新的Lock
对象,并将其用作基础锁。此类为not thread safe。
-
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. 信号量¶
18.5.7.2.1. 信号量¶
- class
asyncio.
Semaphore
(value=1, *, loop=None)¶ 信号量实现。
信号量管理器有一个内部计数器,当调用
acquire()
时递减,调用release()
时递增。计数器永远不会低于零;当acquire()
发现它为零时,它阻塞,等待其他协程调用release()
。信号量对象也还支持上下文管理协议。
可选参数给出内部计数器的初始值;它默认为
1
。如果给定的值小于0
,则会引发ValueError
。此类为不是线程安全的。
- coroutine
acquire
()¶ 获取信号量。
如果内部计数器在输入时大于零,则将其减1并立即返回
True
。如果在入口处为零,则阻塞,等待直到一些其他协程调用release()
使其大于0
,然后返回True
此方法是coroutine。
-
locked
()¶ 如果不能立即获取信号量,则返回
True
。
-
release
()¶ 释放信号量,将内部计数器递增1。当它在进入时为零,并且另一个协程等待它再次变得大于零时,唤醒协程。
- coroutine
18.5.7.2.2. BoundedSemaphore¶
- class
asyncio.
BoundedSemaphore
(value=1, *, loop=None)¶ 有界信号量实现。从
Semaphore
继承。此引发
release()
中的ValueError
如果它将增加的值高于初始值。