web-dev-qa-db-ja.com

.Semaphore()と.BoundedSemaphore()の違いは何ですか?

threading.Lock()threading.Semaphore(1)と等しいことを知っています。

また、threading.Lock()threading.BoundedSemaphore(1)と同じですか?

そして、新しくthreading.BoundedSemaphore()に会いましたが、これらの違いは何ですか?次のコードスニペットなど(スレッドに制限を適用するため):

import threading

sem = threading.Semaphore(5)
sem = threading.BoundedSemaphore(5)
7
Benyamin Jafari

Semaphoreは、取得した回数よりも多く解放される可能性があり、その場合、カウンターが開始値よりも高くなります。 BoundedSemaphoreできません 開始値より上に上げます。

from threading import Semaphore, BoundedSemaphore

# Usually, you create a Semaphore that will allow a certain number of threads
# into a section of code. This one starts at 5.
s1 = Semaphore(5)

# When you want to enter the section of code, you acquire it first.
# That lowers it to 4. (Four more threads could enter this section.)
s1.acquire()

# Then you do whatever sensitive thing needed to be restricted to five threads.

# When you're finished, you release the semaphore, and it goes back to 5.
s1.release()


# That's all fine, but you can also release it without acquiring it first.
s1.release()

# The counter is now 6! That might make sense in some situations, but not in most.
print(s1._value)  # => 6

# If that doesn't make sense in your situation, use a BoundedSemaphore.

s2 = BoundedSemaphore(5)  # Start at 5.

s2.acquire()  # Lower to 4.

s2.release()  # Go back to 5.

try:
    s2.release()  # Try to raise to 6, above starting value.
except ValueError:
    print('As expected, it complained.')    
14
Don Kirkby

スレッドモジュールは、単純なSemaphoreクラスを提供します。

Semaphoreは、増分のためにrelease()を何度でも呼び出すことができる無制限のカウンターを提供します。

ただし、プログラミングエラーを回避するために、通常はBoundedSemaphoreを使用するのが正しい選択です。これにより、release()呼び出しがカウンターを最大サイズを超えて増加させようとするとエラーが発生します。

[〜#〜]編集[〜#〜]

セマフォには、ロックフラグ(ロックの場合)ではなく内部カウンターがあり、指定された数を超えるスレッドがセマフォを保持しようとした場合にのみブロックされます。セマフォの初期化方法に応じて、これにより、複数のスレッドが同じコードセクションに同時にアクセスできるようになります。

1