Mutex ロックは、最も単純なスレッド同期メカニズムです。Python によって提供される Condition オブジェクトは、複雑なスレッド同期の問題をサポートします。 Condition は条件変数と呼ばれ、Lock と同様の取得メソッドと解放メソッドを提供するだけでなく、待機メソッドと通知メソッドも提供します。スレッドは最初に条件変数を取得し、次にいくつかの条件を決定します。条件が満たされない場合は待機し、条件が満たされた場合は条件を変更する処理を実行し、通知を受け取った後に待機状態にある他のスレッドに条件を再判断します。このプロセスは、複雑な同期問題を解決するために継続的に繰り返されます。
Condition オブジェクトはロック (Lock/RLock) と待機プールを維持すると考えることができます。スレッドは、取得によって Condition オブジェクトを取得します。wait メソッドが呼び出されると、スレッドは Condition 内のロックを解放し、同時に待機プールに記録されます。通知メソッドが呼び出されると、Condition オブジェクトは待機プールからスレッドを選択し、取得メソッドを呼び出してロックの取得を試みるよう通知します。
Condition オブジェクトのコンストラクターは、Lock/RLock オブジェクトをパラメーターとして受け入れることができます。指定されていない場合、Condition オブジェクトは内部で RLock を作成します。
Notice メソッドに加えて、Condition オブジェクトは、待機プール内のすべてのスレッドに内部ロックの取得を試みるよう通知できる、notifyAll メソッドも提供します。上記の仕組みにより、待機状態のスレッドはnotifyメソッドでしか起動できないため、スレッドが永久に沈黙することを防ぐのがnotifyAllの機能です。
条件変数の同期を示す古典的な問題は、生産者と消費者の問題です。市場を通じて製品と対話する生産者のグループ (Producer) と消費者のグループ (Consumer) があると仮定します。生産者の「戦略」は、市場に製品が 1,000 個未満残っている場合は 100 個の製品を生産し、市場に投入することですが、消費者の「戦略」は、市場に製品が 100 個以上残っている場合は 100 個の製品を生産することです。 . 3つの製品を消費します。 Condition を使用してプロデューサーとコンシューマーの問題を解決するコードは次のとおりです:
import threading import time class Producer(threading.Thread): def run(self): global count while True: if con.acquire(): if count > 1000: con.wait() else: count = count+100 msg = self.name+' produce 100, count=' + str(count) print msg con.notify() con.release() time.sleep(1) class Consumer(threading.Thread): def run(self): global count while True: if con.acquire(): if count < 100: con.wait() else: count = count-3 msg = self.name+' consume 3, count='+str(count) print msg con.notify() con.release() time.sleep(1) count = 500 con = threading.Condition() def test(): for i in range(2): p = Producer() p.start() for i in range(5): c = Consumer() c.start() if __name__ == '__main__': test()