18.5.7. 同步原语 — Python 文档

来自菜鸟教程
Python/docs/3.6/library/asyncio-sync
跳转至:导航、​搜索

18.5.7. 同步原语

源代码: :source:`Lib/asyncio/locks.py`

锁:

信号量:

异步锁 API 被设计为接近 threading 模块的类(LockEventCondition、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