Synchronization Primitives

源代码: Lib/asyncio/locks.py


asyncio 同步 Primitives 的设计类似于threading模块的 Primitives,但有两个重要警告:

asyncio 具有以下基本同步 Primitives:


Lock

异步锁可用于保证对共享资源的独占访问。

使用 Lock 的首选方式是async with语句:

lock = asyncio.Lock()

# ... later
async with lock:
    # access shared state

等效于:

lock = asyncio.Lock()

# ... later
await lock.acquire()
try:
    # access shared state
finally:
    lock.release()

从 3.8 版开始不推荐使用,将在 3.10 版中删除:* loop *参数。

该方法一直等到锁定被* unlocked 解锁,将其设置为 locked *并返回True

如果在acquire()中阻止了一个协程 await 释放锁,则finally只有一个协程进行。

获得锁是“公平的”:continue 执行的协程将是开始 await 锁的第一个协程。

当锁定为* locked 时,将其重置为 unlocked *并返回。

如果锁是* unlocked *,则引发RuntimeError

Event

异步事件可用于通知多个异步任务某个事件已发生。

事件对象 Management 一个内部标志,该内部标志可以passset()方法设置为* true ,并passclear()方法设置为 false wait()方法阻塞,直到标志设置为 true 为止。该标志最初设置为 false *。

从 3.8 版开始不推荐使用,将在 3.10 版中删除:* loop *参数。

Example:

async def waiter(event):
    print('waiting for it ...')
    await event.wait()
    print('... got it!')

async def main():
    # Create an Event object.
    event = asyncio.Event()

    # Spawn a Task to wait until 'event' is set.
    waiter_task = asyncio.create_task(waiter(event))

    # Sleep for 1 second and set the event.
    await asyncio.sleep(1)
    event.set()

    # Wait until the waiter task is finished.
    await waiter_task

asyncio.run(main())

如果设置了事件,请立即返回True。否则,阻塞直到另一个任务调用set()

await 事件设置的所有任务将立即唤醒。

现在,在wait()上 await 的任务将阻塞,直到再次调用set()方法。

Condition

任务可以使用异步条件 Primitives 来 await 某个事件发生,然后获得对共享资源的独占访问。

本质上,Condition 对象结合了EventLock的Function。可能有多个 Condition 对象共享一个 Lock,这允许在对该共享资源的特定状态感兴趣的不同任务之间协调对共享资源的排他访问。

可选的* lock *参数必须是Lock对象或None。在后一种情况下,将自动创建一个新的 Lock 对象。

从 3.8 版开始不推荐使用,将在 3.10 版中删除:* loop *参数。

使用条件的首选方式是async with语句:

cond = asyncio.Condition()

# ... later
async with cond:
    await cond.wait()

等效于:

cond = asyncio.Condition()

# ... later
await cond.acquire()
try:
    await cond.wait()
finally:
    cond.release()

该方法一直等到基础锁定被* unlocked 解锁,将其设置为 locked *并返回True

必须在调用此方法之前获取该锁,并在此之后不久将其释放。如果使用“ *解锁”锁调用,则会引发RuntimeError错误。

此方法的作用类似于notify(),但是唤醒所有 await 的任务。

必须在调用此方法之前获取该锁,并在此之后不久将其释放。如果使用“ *解锁”锁调用,则会引发RuntimeError错误。

在解锁的锁上调用时,将引发RuntimeError

如果在调用此方法时调用任务尚未获取锁,则会引发RuntimeError

此方法释放基础锁,然后阻塞,直到被notify()notify_all()调用唤醒。唤醒后,Condition 重新获取其锁定,此方法返回True

谓词必须是可调用的,其结果将被解释为布尔值。finally值是返回值。

Semaphore

signal 量 Management 一个内部计数器,该内部计数器由每个acquire()调用递减,并由每个release()调用递增。计数器永远不能低于零。当acquire()发现它为零时,它将阻塞,直到某些任务调用release()为止。

可选的* value *参数给出内部计数器的初始值(默认为1)。如果给定值小于0,则引发ValueError

从 3.8 版开始不推荐使用,将在 3.10 版中删除:* loop *参数。

使用 signal 量的首选方法是async with语句:

sem = asyncio.Semaphore(10)

# ... later
async with sem:
    # work with shared resource

等效于:

sem = asyncio.Semaphore(10)

# ... later
await sem.acquire()
try:
    # work with shared resource
finally:
    sem.release()

如果内部计数器大于零,则将其递减一并立即返回True。如果为零,请 await 直到调用release()并返回True

BoundedSemaphore不同,Semaphore允许进行release()通话多于acquire()通话。

BoundedSemaphore

有界 signal 量是Semaphore的一个版本,如果它将内部计数器增加到初始* value *以上,则会在release()中引发ValueError

从 3.8 版开始不推荐使用,将在 3.10 版中删除:* loop *参数。


从 3.7 版开始不推荐使用:不推荐使用await lockyield from lock和/或with语句(with await lockwith (yield from lock))获取锁。改用async with lock

首页