18.5.7. 同期プリミティブ¶
ソースコード: Lib/asyncio/locks.py
ロック:
セマフォ:
asyncio lock API は threading
モジュールのクラス (Lock
, Event
, Condition
, Semaphore
, BoundedSemaphore
) に近くなるよう設計されましたが、 timeout 引数はありません。
asyncio.wait_for()
関数を用いてタイムアオウト後にタスクをキャンセルすることが出来ます。
18.5.7.1. ロック¶
18.5.7.1.1. Lock¶
-
class
asyncio.
Lock
(*, loop=None)¶ プリミティブなロックオブジェクトです。
プリミティブロックは、ロックされたときに特定のコルーチンに所有されない同期プリミティブです。プリミティブロックは 'ロック状態' か 'アンロック状態' のどちらかの状態になります。
これはアンロック状態で作成されます。基本メソッド
acquire()
とrelease()
を持ちます。アンロック状態のとき、acquire() でロック状態に変更し直ちに返します。ロック状態のとき、acquire() は、他のコルーチンが release() を呼び出しアンロック状態に変更するまでブロックします。その後 acquire() はそれをロック状態にして返します。release() メソッドはロック状態のとき以外に呼び出してはなりません; これは状態をアンロック状態に変更して直ちに返します。アンロック状態でロック解除を行おうとするとRuntimeError
が送出されます。1 個以上のコルーチンが acquire() でブロックされ、アンロック状態への変更を待っている場合、release() が呼び出されアンロック状態にリセットされたとき 1 個のコルーチンのみが開始されます; 最初に 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. Event¶
-
class
asyncio.
Event
(*, loop=None)¶ threading.Event
と等価で非同期な Event 実装です。イベントオブジェクトを実装するクラスです。イベントは
set()
メソッドで真に設定され、clear()
メソッドで偽にリセットされるフラグを管理します。wait()
メソッドはフラグが真になるまでブロックします。フラグの最初の値は偽です。このクラスは スレッド安全ではありません。
-
is_set
()¶ 内部フラグが真のとき
True
を返します。
-
18.5.7.1.3. Condition¶
-
class
asyncio.
Condition
(lock=None, *, loop=None)¶ threading.Condition
と等価で非同期な Condition 実装です。このクラスは条件変数オブジェクトを実装しています。条件変数は 1 個以上のコルーチンが他のコルーチンから通知を受けるまで待機できるようにします。
引数 lock に非
None
が与えられた場合、それはLock
オブジェクトでなければなりません。これは下層のロックとして使用されます。与えられない場合、新しくLock
オブジェクトが作成されます。このクラスは スレッド安全ではありません。
-
coroutine
acquire
()¶ 下層でのロックを獲得します。
このメソッドはロックが解除されるまでブロックし、ロック状態に変更して
True
を返します。このメソッドは コルーチン です。
-
notify
(n=1)¶ デフォルトでは、この条件を待機しているコルーチンがあればそれが再開されます。呼び出したコルーチンがこのロックを獲得していない状態でこのメソッドが呼び出されると
RuntimeError
が送出されます。このメソッドではこの条件変数を待機しているうち最大で n 個のコルーチンが再開されます; 待機しているコルーチンがなければ何もしません。
-
locked
()¶ 下層のロックを獲得していれば
True
を返します。
-
notify_all
()¶ この条件を待機しているすべてのコルーチンを再開します。このメソッドは
notify()
のように振る舞いますが、1 個ではなくすべてのコルーチンが再開されます。呼び出したコルーチンがロックを獲得していない状態でこのメソッドが呼び出されるとRuntimeError
が送出されます。
-
release
()¶ 下層のロックを解除します。
ロックがロック状態のとき、アンロック状態にリセットされます。他にこのロックの解除を待機していたコルーチンが存在していた場合、そのうちの一つが再開されます。
アンロック状態のロックに対して呼び出された場合、
RuntimeError
が送出されます。戻り値はありません。
-
coroutine
wait
()¶ 通知を受けるまで待機します。
呼び出したコルーチンがロックを獲得していない状態でこのメソッドが呼び出されると、
RuntimeError
が送出されます。このメソッドは下層のロックを解除し、その後それが他のコルーチンで同じ条件変数の
notify()
かnotify_all()
によって再開されるまでブロックします。再開されると、再びロックを獲得してTrue
を返します。このメソッドは コルーチン です。
-
coroutine
18.5.7.2. セマフォ¶
18.5.7.2.1. Semaphore¶
-
class
asyncio.
Semaphore
(value=1, *, loop=None)¶ Semaphore 実装です。
セマフォは
acquire()
の呼び出しで減算し、release()
で加算する内部カウンターを管理します。カウンターは負数になることはありません;acquire()
が呼び出されたときにセマフォがゼロであればブロックされ、他のコルーチンがrelease()
を呼び出すまで待機します。セマフォはコンテキストマネージャープロトコルもサポートしています。
任意の引数 value で内部カウンターの初期値を指定できます; デフォルトは
1
です。value に0
未満の値が指定されると、ValueError
が送出されます。このクラスは スレッド安全ではありません。
-
coroutine
acquire
()¶ セマフォを獲得します。
入力時内部カウンターがゼロより大きかった場合、1 減算され、直ちに
True
を返します。ゼロだった場合、ブロックされ、他のコルーチンがrelease()
を呼び出してカウンター値が0
より大きくなるまで待機し、獲得できるとTrue
を返します。このメソッドは コルーチン です。
-
locked
()¶ セマフォを直ちに獲得できない場合
True
を返します。
-
release
()¶ セマフォを解放し、内部カウンターを 1 加算します。カウンター値がゼロで他のコルーチンが待機状態にあった場合、加算後そのコルーチンが再開されます。
-
coroutine
18.5.7.2.2. BoundedSemaphore¶
-
class
asyncio.
BoundedSemaphore
(value=1, *, loop=None)¶ Semaphore
を継承した有限セマフォの実装です。release()
内でカウンター値が加算されて引数 value を超えるとValueError
を送出します。