同步原语¶
源代码: Lib/asyncio/locks.py
异步同步原语的设计与 threading
有两个重要注意事项的模块:
异步原语不是线程安全的,因此不应将它们用于OS线程同步(使用
threading
为此);这些同步原语的方法不接受 timeout 参数;使用
asyncio.wait_for()
函数执行超时操作。
Asyncio具有以下基本同步原语:
锁¶
- class asyncio.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()
- coroutine acquire()¶
获取锁。
此方法等待直到锁 解锁 将它设置为 锁定的 回报
True
.当一个以上的协程被阻塞时
acquire()
等待锁被解锁,最终只有一个协同程序进行。获取锁是 fair :继续进行的协程将是第一个开始等待锁的协程。
- release()¶
释放锁。
当锁是 锁定的 将其重置为 解锁 然后回来。
如果锁是 解锁 ,A
RuntimeError
提高了。
- locked()¶
返回
True
如果锁是 锁定的 .
事件¶
- class asyncio.Event¶
事件对象。不是线程安全的。
Asyncio事件可用于通知多个Asyncio任务发生了某些事件。
事件对象管理一个内部标志,该标志可以设置为 true 使用
set()
方法,并重置为 错误 使用clear()
方法。这个wait()
方法会一直阻塞,直到将标志设置为 true 。该标志设置为 错误 最初是这样的。例子::
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())
- set()¶
设置事件。
等待事件设置的所有任务都将立即唤醒。
- is_set()¶
返回
True
如果事件已设置。
条件¶
- class asyncio.Condition(lock=None)¶
条件对象。不是线程安全的。
任务可以使用asyncio条件原语等待某个事件发生,然后以独占方式访问共享资源。
实际上,条件对象结合了
Event
和ALock
.可以让多个条件对象共享一个锁,这允许在对共享资源的特定状态感兴趣的不同任务之间协调对共享资源的独占访问。可选的 lock 参数必须是
Lock
对象或None
. 在后一种情况下,会自动创建一个新的锁对象。使用条件的首选方法是
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()
- coroutine acquire()¶
获取基础锁。
此方法等待,直到基础锁 解锁 将它设置为 锁定的 回报
True
.
- notify(n=1)¶
最多唤醒 n 等待此条件的任务(默认为1)。如果没有任务等待,则该方法为no op。
必须先获取锁,然后才能调用此方法并在不久后释放。如果使用 解锁 锁定A
RuntimeError
出现错误。
- locked()¶
返回
True
如果获取了基础锁。
- notify_all()¶
唤醒在此条件下等待的所有任务。
这种方法的作用就像
notify()
,但唤醒所有等待的任务。必须先获取锁,然后才能调用此方法并在不久后释放。如果使用 解锁 锁定A
RuntimeError
出现错误。
- release()¶
释放基础锁。
在未锁定的锁上调用时,
RuntimeError
提高了。
- coroutine wait()¶
等待通知。
如果调用此方法时调用任务未获取锁,则
RuntimeError
提高了。此方法释放基础锁,然后阻塞,直到被
notify()
或notify_all()
调用。一旦被唤醒,条件将重新获取其锁,此方法将返回True
.
- coroutine wait_for(predicate)¶
等待谓词变为 true .
谓词必须是可调用的,其结果将被解释为布尔值。最终值是返回值。
Semaphore¶
- class asyncio.Semaphore(value=1)¶
信号量对象。不是线程安全的。
信号量管理一个内部计数器,该计数器由每个计数器递减
acquire()
调用并递增release()
调用。计数器永远不能低于零;何时acquire()
发现它是零,它会阻塞,等待一些任务调用release()
.可选的 value 参数提供内部计数器的初始值 (
1
默认情况下)。如果给定值小于0
一ValueError
提高了。使用信号量的首选方法是
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()
- locked()¶
返回
True
如果不能立即获取信号量。
- release()¶
释放一个信号量,将内部计数器递增一个。无法唤醒等待获取信号量的任务。
不像
BoundedSemaphore
,Semaphore
允许制造更多release()
调用比acquire()
调用。
BoundedSemaphore¶
- class asyncio.BoundedSemaphore(value=1)¶
有界信号量对象。不是线程安全的。
有界信号量是
Semaphore
提出一个ValueError
在里面release()
如果它使内部计数器高于初始计数器 value .
在 3.9 版更改: 使用获取锁 await lock
或 yield from lock
和/或 with
陈述 (with await lock
, with (yield from lock)
)已删除。使用 async with lock
相反。