「スピンロック」とは正確には何ですか?


108

私はいつもそれらが何であるかを疑問に思いました:それらを聞くたびに、未来のフライホイールのようなデバイスのイメージが私の心の中を踊っています(ローリング?)...

彼らは何ですか?

回答:


125

通常のロック(ミューテックス、クリティカルセクションなど)を使用する場合、オペレーティングシステムはスレッドをWAIT状態にし、同じコア上の他のスレッドをスケジュールすることによってスレッドをプリエンプトします。スレッドがCPU時間を再び受け取るためにプリエンプションを待機する必要があるため、待機時間が本当に短い場合、これはパフォーマンスを低下させます。

さらに、カーネルオブジェクトは、割り込みハンドラーやページングが利用できない場合など、カーネルのすべての状態で利用できるわけではありません。

スピンロックはプリエンプションを引き起こしませんが、他のコアがロックを解放するまでループ(「スピン」)で待機します。これにより、スレッドがクォンタムを失うのを防ぎ、ロックが解放されるとすぐに続行します。スピンロックの単純なメカニズムにより、カーネルはほとんどすべての状態でそれを利用できます。

そのため、シングルコアマシンのスピンロックは、スレッドのスケジューリングを完全に妨げる「割り込みの無効化」または「IRQLの発生」にすぎません。

スピンロックにより、最終的にカーネルは「ビッグカーネルロック」(コアがカーネルに入り、出口で解放されるときに取得されるロック)を回避し、カーネルプリミティブをきめ細かくロックできるため、マルチコアマシンでのマルチプロセッシングが向上し、パフォーマンスが向上します。

編集:質問が出てきました:「それは、可能な限りスピンロックを使用する必要があるということですか?」そして私はそれに答えようとします:

先に述べたように、スピンロックは、予想される待機時間がクォンタム(読み取り:ミリ秒)よりも短く、プリエンプションがあまり意味がない(たとえば、カーネルオブジェクトが利用できない)場合にのみ役立ちます。

待機時間が不明な場合、またはユーザーモードの場合、スピンロックは効率的ではありません。スピンロックが利用可能かどうかを確認しながら、待機中のコアで100%のCPU時間を消費します。クォンタムが期限切れになるまで、そのコアで他のスレッドが実行されないようにします。このシナリオは、カーネルレベルでの短いバーストでのみ実行可能であり、ユーザーモードアプリケーションのオプションではありそうもありません。

SOについての質問は次のとおりです:スピンロック、それらはどれほど便利ですか?


可能な限りスピンロック(ミューテックス、クリティカルセクションなどではなく)を行う必要があるという意味ですか?

1
私が間違っている場合、誰かが私を訂正してください。ただし、スピンロックはプリエンプションを無効にしません(つまり、再スケジュール)。単純な理由により、スピンロックが別のプロセスによってロックされたリソースを待機している場合、その2番目のプロセスには、実行してリソースを解放する機会を与える必要があります。または、2番目のプロセスを実行するには、最初の(スピン)プロセスをプリエンプトする必要があります。
user1284631 2012年

代わりにスピンロックが行うことは、プロセスの状態をTASK_RUNNINGからTASK_INTERRUPTIBLE(スリープ状態)に変更しないため、そのプロセスに関するすべて(メモリ、キャッシュなど)を保存しないことです。代わりに、スピニングプロセスはプリエンプトされますが、「即時にスケジュール可能な」プロセスは決して終了しません。それはメモリに保持され、他のプロセスは、スピナーが待機しているリソースを解放するまで定期的に実行されます。そのとき、スピンロックは単純に戻り、スピニングプロセスを続行できます。常にTASK_RUNNING状態で待機します。
user1284631

1
あなたはそれについて正しいです(これも参照してください:linuxjournal.com/article/5833)。しかし、リソースをロックして割り込みを無効にすることは、共同で実行するのに役立ちますが、それ以外の場合は無関係な概念です。基本的に、矛盾した状態にあるリソースを使用していないことを確認したいので、そのロックをテストします。割り込みを無効にすると(プリエンプションも)、はい、あなたがそれを扱っている間、誰もあなたの復活を台無しにすることはありません。ただし、そのためには、リソースを取得するときにリソースが解放されていることを確認する必要があります。
user1284631

1
(次に、割り込みを無効にして、他のタスクがあなたを横取りしてリソースをいじっていないことを確認します)。UP(ユニプロセッサ)では、これが常に当てはまります。最初の(および後続の)スピンロックが単純に許可され、割り込み(つまりプリエンプション)が無効になり、リソースを使用するタスクがプリエンプトされることはありません。リソースでジョブを実行してから、割り込みを有効にします(したがって、プリエンプションを有効にします)。プリエンプションが有効な場合、リソースはすでに解放されています。基本的には、UPに、何のスピンロック競合が存在しない何の待機はありません。SMPではそうかもしれません。
user1284631

25

リソースがロックによって保護されているとしましょう。リソースへのアクセスを希望するスレッドは、最初にロックを取得する必要があります。ロックが使用できない場合、スレッドはロックが解放されたかどうかを繰り返し確認する可能性があります。この間、スレッドはビジー状態で待機し、ロックをチェックし、CPUを使用しますが、有用な作業は行いません。このようなロックは、スピンロックと呼ばれます。


2
素敵な答え!+1
Jayesh Bhoi

18

特定の条件が満たされるまでループが続くのは、かなりループです。

while(cantGoOn) {};

1
および/またはwhile(cantGoOn){sleep(0)};
Jiminion

@Jiminionを指定するとsleep(0)、スレッドがプリエンプトされ、そもそもスピンロックを使用する目的が失われます。他のスレッドに譲る必要がある場合は、通常のロックを使用する必要があります。(私はあなたのコメントが非常に古いことを知っていますが、他の人がこれを提案として見ないようにしたいと思いました)。
セダットカパノグル2018年

「値がゼロの場合、スレッドは残りのタイムスライスを実行可能な他のスレッドに放棄します。実行可能な他のスレッドがない場合、関数はすぐに戻り、スレッドは実行を継続します。」
Jiminion



3

SpinLocksは、ロックが使用可能になるまでスレッドが待機するものです。これは通常、カーネルオブジェクトをある期間内に取得するスコープがある場合に、カーネルオブジェクトを取得するオーバーヘッドを回避するために使用されます。

例:

While(SpinCount-- && Kernel Object is not free)
{}

try acquiring Kernel object

3

リソースがロックされているときにブロックするのではなく、ビジー待機ループに入ってリソースをプールする方が安価であると考えられる場合は、スピンロックを使用することをお勧めします。

スピンは、ロックの粒度が細かく、数が多い場合(リンクリストのノードごとのロックなど)、およびロックの保持時間が常に非常に短い場合に役立ちます。一般に、スピンロックを保持している間は、ブロック、それ自体がブロックする可能性があるものの呼び出し、一度に複数のスピンロックを保持、動的にディスパッチされた呼び出し(インターフェイスと仮想)、静的にディスパッチされた呼び出しを任意のコードに行うことを避ける必要があります所有、またはメモリを割り当てます。

パフォーマンス上の理由から、SpinLockは値の型であることに注意することも重要です。したがって、2つのインスタンス(元のインスタンスとコピー)は互いに完全に独立しているため、誤ってSpinLockインスタンスをコピーしないように十分注意する必要があります。これにより、アプリケーションの誤動作が発生する可能性があります。SpinLockインスタンスを渡す必要がある場合は、値ではなく参照で渡す必要があります。


1

簡単に言えば、スピンロックは、アトミックな比較とスワップ(CAS)またはテストと設定のような命令を使用して、ロックフリー、ウェイトフリーのスレッドセーフなイディオムを実装します。このような構造は、マルチコアマシンで十分に拡張できます。


厳密に言うと、スピンロックはロックフリーやウェイトフリーの実装には使用されません。
rdb 2016年

0

これは、条件が満たされるまで回転するループです。


0

まあ、はい-スピンロック(従来のクリティカルセクションなど)のポイントは、特定の状況(マルチコアシステムなど)でより優れたパフォーマンスを提供することです。これは、スレッドの残りのクォンタムがすぐに得られないためです。


0

スピンロックはロックの一種であり、ブロック不可であり、スリープ不可です。共有リソースまたは重要なリソースのスピンロックを取得しようとするスレッドは常にスピンし、指定されたリソースのロックを取得するまでCPU処理サイクルを浪費します。スピンロックが取得されると、クォンタムで作業を完了し、リソースをそれぞれ解放しようとします。スピンロックは最も優先度の高いロックタイプであり、簡単に言うと、非プリエンプティブな種類のロックです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.