18.5.7. 同步原语 — Python 文档
18.5.7. 同步原语
源代码: :source:`Lib/asyncio/locks.py`
锁:
信号量:
异步锁 API 被设计为接近 threading 模块的类(Lock、Event、Condition、Semaphore[ X151X], 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()中阻塞等待状态变为unlocked时,当release()调用将状态重置为unlocked时,只有一个协程继续; 正在处理在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
。
- release()
释放锁。
当锁被锁定时,将其重置为解锁,然后返回。 如果任何其他协程在等待锁被解锁时被阻塞,只允许其中一个协程继续进行。
当在解锁的锁上调用时,会引发 RuntimeError。
没有返回值。
18.5.7.1.2. 事件
- class asyncio.Event(\*, loop=None)
一个事件实现,异步等效于 threading.Event。
实现事件对象的类。 事件管理一个标志,该标志可以使用 set() 方法设置为 true,并使用 clear() 方法重置为 false。
wait()
方法阻塞,直到标志为真。 该标志最初为假。此类是 不是线程安全的 。
- clear()
将内部标志重置为 false。 随后,调用
wait()
的协程将阻塞,直到调用 set() 再次将内部标志设置为 true。
- is_set()
当且仅当内部标志为真时返回
True
。
- set()
将内部标志设置为 true。 所有等待它成为现实的协程都被唤醒。 一旦标志为真,调用
wait()
的协程根本不会阻塞。
18.5.7.1.3。 健康)状况
- class asyncio.Condition(lock=None, \*, loop=None)
条件实现,异步等效于 threading.Condition。
此类实现条件变量对象。 条件变量允许一个或多个协程等待,直到它们被另一个协程通知。
如果给出了 lock 参数而不是
None
,它必须是一个 Lock 对象,并且它被用作底层锁。 否则,将创建一个新的 Lock 对象并将其用作底层锁。此类是 不是线程安全的 。
- notify(n=1)
默认情况下,唤醒一个等待此条件的协程(如果有)。 如果调用此方法时调用协程尚未获取锁,则会引发 RuntimeError。
该方法最多唤醒n个等待条件变量的协程; 如果没有协程在等待,则为空操作。
笔记
一个被唤醒的协程实际上不会从它的
wait()
调用中返回,直到它可以重新获取锁。 由于 notify() 不释放锁,它的调用者应该。
- locked()
如果获取了底层锁,则返回
True
。
- notify_all()
唤醒所有等待这种情况的协程。 此方法的作用类似于 notify(),但唤醒所有等待的协程而不是一个。 如果调用此方法时调用协程尚未获取锁,则会引发 RuntimeError。
- release()
释放底层锁。
当锁被锁定时,将其重置为解锁,然后返回。 如果任何其他协程在等待锁被解锁时被阻塞,只允许其中一个协程继续进行。
当在解锁的锁上调用时,会引发 RuntimeError。
没有返回值。
18.5.7.2. 信号量
18.5.7.2.1。 信号
- class asyncio.Semaphore(value=1, \*, loop=None)
信号量实现。
信号量管理一个内部计数器,该计数器由每个
acquire()
调用递减,并由每个 release() 调用递增。 计数器永远不会低于零; 当acquire()
发现它为零时,它会阻塞,等待其他一些协程调用 release()。信号量也支持上下文管理协议。
可选参数给出内部计数器的初始值; 默认为
1
。 如果给定的值小于0
,则会引发 ValueError。此类是 不是线程安全的 。
- locked()
如果不能立即获取信号量,则返回
True
。
- release()
释放信号量,将内部计数器加一。 当它在进入时为零并且另一个协程正在等待它再次变得大于零时,唤醒该协程。
18.5.7.2.2. 有界信号量
- class asyncio.BoundedSemaphore(value=1, \*, loop=None)
有界信号量实现。 继承自 信号量 。
如果将值增加到初始值以上,则会在 release() 中引发 ValueError。