同步原語(yǔ)?
asyncio 同步原語(yǔ)被設(shè)計(jì)為與 threading 模塊的類(lèi)似,但有兩個(gè)關(guān)鍵注意事項(xiàng):
asyncio 原語(yǔ)不是線程安全的,因此它們不應(yīng)被用于 OS 線程同步 (而應(yīng)當(dāng)使用
threading);這些同步原語(yǔ)的方法不接受 timeout 參數(shù);請(qǐng)使用
asyncio.wait_for()函數(shù)來(lái)執(zhí)行帶有超時(shí)的操作。
asyncio 具有下列基本同步原語(yǔ):
Lock?
-
class
asyncio.Lock(*, loop=None)? 實(shí)現(xiàn)一個(gè)用于 asyncio 任務(wù)的互斥鎖。 非線程安全。
asyncio 鎖可被用來(lái)保證對(duì)共享資源的獨(dú)占訪問(wèn)。
使用 Lock 的推薦方式是通過(guò)
async with語(yǔ)句:lock = asyncio.Lock() # ... later async with lock: # access shared state
這等價(jià)于:
lock = asyncio.Lock() # ... later await lock.acquire() try: # access shared state finally: lock.release()
-
coroutine
acquire()? 獲取鎖。
此方法會(huì)等待直至鎖為 unlocked,將其設(shè)為 locked 并返回
True。當(dāng)有一個(gè)以上的協(xié)程在
acquire()中被阻塞則會(huì)等待解鎖,最終只有一個(gè)協(xié)程會(huì)被執(zhí)行。鎖的獲取是 公平的: 被執(zhí)行的協(xié)程將是第一個(gè)開(kāi)始等待鎖的協(xié)程。
-
release()? 釋放鎖。
當(dāng)鎖為 locked 時(shí),將其設(shè)為 unlocked 并返回。
如果鎖為 unlocked,則會(huì)引發(fā)
RuntimeError。
-
locked()? 如果鎖為 locked 則返回
True。
-
coroutine
Event?
-
class
asyncio.Event(*, loop=None)? 事件對(duì)象。 該對(duì)象不是線程安全的。
asyncio 事件可被用來(lái)通知多個(gè) asyncio 任務(wù)已經(jīng)有事件發(fā)生。
Event 對(duì)象會(huì)管理一個(gè)內(nèi)部旗標(biāo),可通過(guò)
set()方法將其設(shè)為 true 并通過(guò)clear()方法將其設(shè)為 false。wait()方法會(huì)阻塞直至該旗標(biāo)被設(shè)為 true。 該旗標(biāo)初始時(shí)將被設(shè)為 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_task asyncio.run(main())
-
set()? 設(shè)置事件。
所有等待事件被設(shè)置的任務(wù)將被立即喚醒。
-
is_set()? 如果事件已被設(shè)置則返回
True。
-
Condition?
-
class
asyncio.Condition(lock=None, *, loop=None)? 條件對(duì)象。 該對(duì)象不是線程安全的。
asyncio 條件原語(yǔ)可被任務(wù)用于等待某個(gè)事件發(fā)生,然后獲取對(duì)共享資源的獨(dú)占訪問(wèn)。
在本質(zhì)上,Condition 對(duì)象合并了
Event和Lock的功能。 多個(gè) Condition 對(duì)象有可能共享一個(gè) Lock,這允許關(guān)注于共享資源的特定狀態(tài)的不同任務(wù)實(shí)現(xiàn)對(duì)共享資源的協(xié)同獨(dú)占訪問(wèn)。可選的 lock 參數(shù)必須為
Lock對(duì)象或None。 在后一種情況下會(huì)自動(dòng)創(chuàng)建一個(gè)新的 Lock 對(duì)象。使用 Condition 的推薦方式是通過(guò)
async with語(yǔ)句:cond = asyncio.Condition() # ... later async with cond: await cond.wait()
這等價(jià)于:
cond = asyncio.Condition() # ... later await cond.acquire() try: await cond.wait() finally: cond.release()
-
coroutine
acquire()? 獲取下層的鎖。
此方法會(huì)等待直至下層的鎖為 unlocked,將其設(shè)為 locked 并返回 returns
True。
-
notify(n=1)? 喚醒最多 n 個(gè)正在等待此條件的任務(wù)(默認(rèn)為 1 個(gè))。 如果沒(méi)有任務(wù)正在等待則此方法為空操作。
鎖必須在此方法被調(diào)用前被獲取并在隨后被快速釋放。 如果通過(guò)一個(gè) unlocked 鎖調(diào)用則會(huì)引發(fā)
RuntimeError。
-
locked()? 如果下層的鎖已被獲取則返回
True。
-
notify_all()? 喚醒所有正在等待此條件的任務(wù)。
此方法的行為類(lèi)似于
notify(),但會(huì)喚醒所有正在等待的任務(wù)。鎖必須在此方法被調(diào)用前被獲取并在隨后被快速釋放。 如果通過(guò)一個(gè) unlocked 鎖調(diào)用則會(huì)引發(fā)
RuntimeError。
-
release()? 釋放下層的鎖。
在未鎖定的鎖調(diào)用時(shí),會(huì)引發(fā)
RuntimeError異常。
-
coroutine
wait()? 等待直至收到通知。
當(dāng)此方法被調(diào)用時(shí)如果調(diào)用方任務(wù)未獲得鎖,則會(huì)引發(fā)
RuntimeError。這個(gè)方法會(huì)釋放下層的鎖,然后保持阻塞直到被
notify()或notify_all()調(diào)用所喚醒。 一旦被喚醒,Condition 會(huì)重新獲取它的鎖并且此方法將返回True。
-
coroutine
wait_for(predicate)? 等待直到目標(biāo)值變?yōu)?true。
目標(biāo)必須為一個(gè)可調(diào)用對(duì)象,其結(jié)果將被解讀為一個(gè)布爾值。 最終的值將為返回值。
-
coroutine
Semaphore?
-
class
asyncio.Semaphore(value=1, *, loop=None)? 信號(hào)量對(duì)象。 該對(duì)象不是線程安全的。
信號(hào)量會(huì)管理一個(gè)內(nèi)部計(jì)數(shù)器,該計(jì)數(shù)器會(huì)隨每次
acquire()調(diào)用遞減并隨每次release()調(diào)用遞增。 計(jì)數(shù)器的值永遠(yuǎn)不會(huì)降到零以下;當(dāng)acquire()發(fā)現(xiàn)其值為零時(shí),它將保持阻塞直到有某個(gè)任務(wù)調(diào)用了release()。可選的 value 參數(shù)用來(lái)為內(nèi)部計(jì)數(shù)器賦初始值 (默認(rèn)值為
1)。 如果給定的值小于0則會(huì)引發(fā)ValueError。使用 Semaphore 的推薦方式是通過(guò)
async with語(yǔ)句。:sem = asyncio.Semaphore(10) # ... later async with sem: # work with shared resource
這等價(jià)于:
sem = asyncio.Semaphore(10) # ... later await sem.acquire() try: # work with shared resource finally: sem.release()
-
coroutine
acquire()? 獲取一個(gè)信號(hào)量。
如果內(nèi)部計(jì)數(shù)器的值大于零,則將其減一并立即返回
True。 如果其值為零,則會(huì)等待直到release()并調(diào)用并返回True。
-
locked()? 如果信號(hào)量對(duì)象無(wú)法被立即獲取則返回
True。
-
release()? 釋放一個(gè)信號(hào)量對(duì)象,將內(nèi)部計(jì)數(shù)器的值加一。 可以喚醒一個(gè)正在等待獲取信號(hào)量對(duì)象的任務(wù)。
不同于
BoundedSemaphore,Semaphore允許執(zhí)行的release()調(diào)用多于acquire()調(diào)用。
-
coroutine
BoundedSemaphore?
-
class
asyncio.BoundedSemaphore(value=1, *, loop=None)? 綁定的信號(hào)量對(duì)象。 該對(duì)象不是線程安全的。
BoundedSemaphore 是特殊版本的
Semaphore,如果在release()中內(nèi)部計(jì)數(shù)器值增加到初始 value 以上它將引發(fā)一個(gè)ValueError。
3.7 版后已移除: Acquiring a lock using await lock or yield from lock and/or
with statement (with await lock, with (yield from
lock)) is deprecated. Use async with lock instead.
