それらのパブリックインターフェイスは似ています。 ドキュメント は、SemaphoreSlimが軽量の代替であり、Windowsカーネルセマフォを使用しないことを示しています。 このリソース は、SemaphoreSlimがはるかに高速であることを示しています。 SemaphoreSlimはどのような状況でSemaphoreよりも意味がありますか?
違いの1つは、SemaphoreSlim
が名前付きセマフォを許可しないことです。名前付きセマフォはシステム全体で使用できます。これは、SemaphoreSlimをプロセス間同期に使用できないことを意味します。
MSDNドキュメント は、「待機時間が非常に短いことが予想される」場合にSemSlimを使用する必要があることも示しています。これは通常、スリムバージョンがほとんどのトレードオフに対してより軽量であるという考えとうまく合致します。
MSDNドキュメント は違いを説明しています。
一文で:
SemaphoreSlimはSpinWaitとMonitorに基づいているため、ロックの取得を待機しているスレッドは、別のスレッドに譲る前にロックを取得するために、しばらくCPUサイクルを燃やしています。それが起こらない場合、スレッドはシステムがコンテキストを切り替え、OSがそのスレッドを再度スケジュールすると、(いくつかのCPUサイクルを燃やすことにより)再試行します。長時間待機すると、このパターンはかなりの量のCPUサイクルを焼き切る可能性があります。そのため、このような実装の最良のシナリオは、ほとんどの時間に待ち時間がなく、ほぼ瞬時にロックを取得できる場合です。
セマフォはOSカーネルの実装に依存しているため、ロックを取得するたびにかなりのCPUサイクルを消費しますが、その後、スレッドはロックを取得するために必要な時間だけスリープします。
「短時間」論争について:
少なくとも SemaphoreSlim MSDNドキュメント は
SemaphoreSlimクラスは、単一のアプリ内での同期に推奨されるセマフォです。
備考セクション。同じセクションは、SemaphoreとSemaphoreSlimの主な違いも示しています。
SemaphoreSlimは、Windowsカーネルセマフォを使用しないSemaphoreクラスの軽量な代替です。 Semaphoreクラスとは異なり、SemaphoreSlimクラスは名前付きシステムセマフォをサポートしていません。ローカルセマフォとしてのみ使用できます。
私はソースコードを見ました here そして、これは私が思いついたものです:
SemaphoreとSemaphoreSlimは、Win32ネイティブハンドルを内部的に使用するWaitHandleから派生しています。そのため、両方をDispose()する必要があります。そのため、スリムが軽量であるという考えは疑わしい。
SemaphoreSlimは内部的にSpinWaitを使用しますが、Semaphoreは使用しません。これにより、待機時間が長くなることが予想される場合、少なくともCPUを詰まらせないという意味で、Semaphoreの方が優れているはずです。