Event同期による O(1) スレッド順序制御
3つのスレッドが並行に起動し、それぞれ
first()、second()、third()
を呼び出します。スレッドの起動順序は不定ですが、出力は必ず
"firstsecondthird" の順序を保証する必要があります。
例1: nums = [1, 2, 3]
出力:
"firstsecondthird"
例2: nums = [1, 3, 2]
出力:
"firstsecondthird"
→ Thread CはThread Bを待機、正しい順序を保証
主要ポイント
from threading import Event
class Foo:
__slots__ = ('e1', 'e2')
def __init__(self) -> None:
self.e1 = Event() # first() 完了通知
self.e2 = Event() # second() 完了通知
def first(self, printFirst) -> None:
printFirst()
self.e1.set() # second() の待機を解除
def second(self, printSecond) -> None:
self.e1.wait() # first() の完了を待機
printSecond()
self.e2.set() # third() の待機を解除
def third(self, printThird) -> None:
self.e2.wait() # second() の完了を待機
printThird()
フローの説明:
1. Thread A: first()
を即座に実行し、e1 をセット
2. Thread B: e1 を待機 → 解除後
second() 実行、e2 をセット
3. Thread C: e2 を待機 →
解除後 third() を実行
| 手法 | 時間計算量 | 空間計算量 | 特徴 |
|---|---|---|---|
| Event(本実装) | O(1) | O(1) | シンプル・高速・推奨 |
| Lock/Mutex | O(1) | O(1) | やや複雑 |
| Condition Variable | O(1) | O(1) | 汎用的だが冗長 |
| Semaphore | O(1) | O(1) | カウント機能あり |
なぜ Event が最適か