You are here:  Home » Python » 同步基元 – 异步I / O(Python教程)(参考资料)

同步原语

asyncio同步原语设计与threading模块类似,有两个重要注意事项:

  • asyncio原语不是线程安全的,因此它们不应该用于OS线程同步(使用threading forthat);
  • 这些同步原语的方法不接受timeout参数;使用asyncio.wait_for()函数进行超时操作.

asyncio具有以下基本同步原语:


锁定

class asyncio.Lock*, loop=None

为asyncio任务实现互斥锁。不是thread-safe.

可以使用asyncio lock来保证对ashared资源的独占访问.

使用Lock的首选方法是async with声明:

lock = asyncio.Lock()# ... laterasync with lock:    # access shared state

相当于:

lock = asyncio.Lock()# ... laterawait lock.acquire()try:    # access shared statefinally:    lock.release()
coroutine acquire

获取锁定

这个方法等到锁定为止unlocked,把它设置为locked并返回True.

release

松开锁

当锁是locked,将其重置为unlocked并返回

如果锁是unlocked, 一个 RuntimeError被养了

locked

返回True如果锁是locked.

事件

class asyncio.Event*, loop=None

一个事件对象。不是thread-safe.

asyncio事件可以用来通知多个asyncio任务,发生了一些事件.

一个Event对象管理一个内部标志,可以设置为true使用set()方法并使用false方法重置为clear()wait()方法阻塞,直到标志设置为true。标志设置为false最初

示例:

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_taskasyncio.run(main())
coroutine wait ( )

等到事件设置好了

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

set

设置活动.

所有等待设置事件的任务都会立即被唤醒.

clear)

清除(未设置)事件.

等待等待wait()现在会阻塞,直到再次调用set()方法.

is_set

如果事件发生,则返回True

/

class asyncio.Condition/ (lock=None, *, loop=None

一个Condition对象。不是thread-safe.

任务可以使用asyncio条件原语来等待forsome事件发生,然后获得对sharedresource的独占访问权.

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

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

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

cond = asyncio.Condition()# ... laterasync with cond:    await cond.wait()

这相当于:

cond = asyncio.Condition()# ... laterawait lock.acquire()try:    await cond.wait()finally:    lock.release()
coroutine acquire

获取底层锁

这个方法一直等到底层锁unlocked,设置为locked并返回True.

notifyn=1

最多醒来n任务(默认为1)等待此条件。如果没有等待任务,该方法是无操作的.

在调用此方法之前必须获取锁定并在此之后不久发布。如果调用unlockedlocka RuntimeError提出错误.

locked

返回True如果获得了潜在的锁定

notify_all

唤醒等待这种情况的所有任务.

这种方法就像notify()但是唤醒所有的waittasks.

必须在调用此方法之前获取锁定并在之后不久发布。如果用unlocked locka调用RuntimeError会出现错误.

release ( )

释放底层锁.

在解锁锁上调用时,RuntimeError israised.

coroutine wait()

等待通知.

如果在调用此方法时调用任务没有获取锁定,则RuntimeError被养了

这个方法释放了底层锁,然后阻塞,直到被notify()要么 notify_all()一旦被唤醒,条件重新获得它的锁定,这个方法回复True.

coroutine wait_forpredicate

等到一个谓词变成true.

谓词必须是可调用的,结果将被解释为布尔值。最终值是有价值.

信号圈

class asyncio.Semaphore (value=1, *, loop=None)

信号量对象。不是thread-safe.

信号量管理一个内部计数器,每个acquire()调用递减一次,并按每个release()调用递增。计数器永远不会低于零;什么时候 acquire()发现它为零,它会阻塞,等待一些任务调用release().

可选的value参数给出内部计数器的初始值(默认为1)。如果给定的值不是0a ValueError被抬起来

使用信号量的首选方法是async with声明:

sem = asyncio.Semaphore(10)# ... laterasync with sem:    # work with shared resource

相当于:

sem = asyncio.Semaphore(10)# ... laterawait sem.acquire()try:    # work with shared resourcefinally:    sem.release()
coroutine acquire

获取信号量

如果内部计数器大于零,则减1并立即返回True。如果它为零,则调用//调试release()并返回True.

locked

返回True如果信号量不能立即获得的话

release

释放一个信号量,将内部计数器递增一个。可以唤醒一个等待获取信号量的任务.

不是BoundedSemaphore, Semaphore允许制作更多release()来电acquire()来电话

Boundsephphore

class asyncio.BoundedSemaphore(value=1, *, loop=None)

一个有界的信号量对象。不是thread-safe.

有限的信号量是Semaphore的一个版本,raisesa ValueErrorrelease()如果它将内部计数器增加到初始值以上value.


自版本3.7以后不推荐使用使用await lockyield from lock获取锁定/或with语句(with await lock, with (yield fromlock))已弃用。使用 async with lockinstead.

评论被关闭。