HOWTO · Python

Python のセマフォ

このガイドでは、セマフォを使用して Python でマルチスレッドを処理する方法について学習します。

このページの内容

このガイドでは、セマフォを使用して Python でマルチスレッドを処理する方法を学習します。 スレッドへのアクセスを同期し、制限された量のリソースを使用するにはどうすればよいですか?

セマフォ

同期コントローラはセマフォです。 セマフォは、スレッドの限られた数のリソースへの同期アクセスを提供します。

セマフォは、現在利用可能なリソースの数を表す変数と見なすことができます。

たとえば、セマフォとして機能するショッピング モールの駐車場には、特定のレベルで利用可能な複数のスペースがあります。

セマフォの値は、使用可能なリソースよりも大きいか小さい必要があります。 acquire と release の操作はセマフォで接続されています。

セマフォの値は、同期に使用されているリソースの 1つがスレッドによって取得されると減少します。 同期リソースの 1つがスレッドによって解放されると、セマフォの値が増加します。

Python のセマフォ

セマフォの概念の Python の実装は、threading モジュールのクラスを使用します。 Semaphore はこのクラスの名前です。

acquire() および release() 関数は、関数コンストラクターと共に Semaphore クラスに含まれています。

セマフォのカウントが 0 より大きい場合、acquire() 関数を使用してカウントを下げます。 そうでない場合は、カウントが 0 より大きくなるまでブロックします。

セマフォ上にあるスレッドの 1つが、release() 関数を使用して起こされます。これにより、セマフォのカウントも増加します。 それでは、セマフォの構文を理解しましょう。

object_name = threading.Semaphore(count)

Semaphore クラス オブジェクトは、上記の構文の object_name で示されます。

一度にアクセスできるスレッドの数は、Semaphore クラスの count 引数によって指定されます。 このパラメーターのデフォルト値は 1 です。

count パラメータの値は、スレッドが acquire() 関数を使用するたびに 1 ずつ減少します。 count パラメータの値は、スレッドが release() 関数を使用するたびに 1 ずつ増加します。

このステートメントによると、acquire() メソッドを呼び出すたびに、count パラメーターの値が減少します。 ただし、release() 関数を呼び出すと、count パラメータの値が増加します。 次のコードを見てください。

# import threading module
import threading

# creating instance of semaphore
sema = threading.Semaphore(1)


def test():
    # appling semaphore
    print(f"Value Of Semaphore --> {sema._value}")
    sema.acquire()
    print(f"acquired lock --> {threading.current_thread().name}")
    print(f"Value Of Semaphore --> {sema._value}")
    print(f"release lock --> {threading.current_thread().name}")
    sema.release()
    print(f"Value Of Semaphore --> {sema._value}")


# initializing threads
t1 = threading.Thread(target=test)
t2 = threading.Thread(target=test)
t3 = threading.Thread(target=test)
# executing threads
t1.start()
t2.start()
t3.start()

上記のコードのように、count が 1 に設定されている場合、スレッドは同期されます。 上記のコードの出力を見ると、それが最初と 2 番目のスレッドであり、3 番目のスレッドが acquire と release の間のコードにアクセスできることがわかります。

Value Of Semaphore --> 1
Value Of Semaphore --> 1
acquired lock --> Thread-1 (test)
Value Of Semaphore --> 0
Value Of Semaphore --> 0
release lock --> Thread-1 (test)
Value Of Semaphore --> 1
acquired lock --> Thread-2 (test)
Value Of Semaphore --> 0
release lock --> Thread-2 (test)
Value Of Semaphore --> 1
acquired lock --> Thread-3 (test)
Value Of Semaphore --> 0
release lock --> Thread-3 (test)
Value Of Semaphore --> 1

count の値を 1 から 2 に変更する場合、一度に 2つのスレッドが制限されたコードにアクセスできるようになります。 したがって、出力は異なります。

Value Of Semaphore --> 2
acquired lock --> Thread-1 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 1
release lock --> Thread-1 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 1
acquired lock --> Thread-3 (test)
acquired lock --> Thread-2 (test)
Value Of Semaphore --> 0
Value Of Semaphore --> 0
release lock --> Thread-2 (test)
release lock --> Thread-3 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 2

セマフォがスレッドを解放するのにかかる時間は、デバイスの速度に基づいており、毎回異なることに注意してください。 セマフォのインスタンスで count の値を変更することで、上記のコードをテストできます。