回答:
ポーリングとは、リソース(あらゆる種類のリソース)の準備ができているかどうかを繰り返し確認することです。
スピンロックは、ポーリングしているリソースがロックの場合です。
ポーリングは悪くないことに注意してください。特に、ポーリングの準備ができているデータが通常ある場合、ポーリングは効率的です。ポーリングは、データを取得せずに行う場合にのみ非効率的です。
一方、中断が頻繁に発生するほど大量のデータがある場合、割り込みは非効率的です。中断する前に実際にいくつかの有用な作業を完了することができるほどデータがまれにしか到着しない場合は、効率的です。
15年前、新しい電子メールが届くたびに私を中断するように電子メールプログラムを設定しました。これは週に1、2回発生しました。受信トレイを常にチェックすることは、膨大な時間の無駄でした。
最近では、すべての通知がオフになっています。私は自分の受信トレイを見るたびにそこに新しいメールがあることを知っています。ポーリングがより効率的になりました。
スピンロックは、ロックが取られるように)可能性が低い場合に有効である、およびb)場合、ロックが取得され、それは短時間だけ保持されます。つまり、ほとんど競合しないきめの細かいロックには効率的ですが、非常に競合するきめの細かいロックには非効率的です。
(そしてもちろん、スピンロックは真の並列処理がある場合にのみ機能します。そうでない場合、他のスレッドはロックを解除する機会がありません。それは明らかなことですが、とにかく述べたいと思います。)
atomically_do { while (lock.is_locked?); lock.acquire! }
)生成される場合、それは空のループではなく、したがってその純粋主義的な見方ではスピンロックではありません:-Dしかし、もちろん、プラトニックな理想への他のタイプのロックまたはリラクゼーション/追加とのハイブリッド化は、現実の世界で完全に理にかなっています。
スピンロックは、具体的には、達成つのロックのタイプである介してポーリングします。
ポーリングは、何かのステータスを確認する方法です(ステータスが通知されるのを待つのではなく、ステータスを要求することにより)。
キーボードキーのステータスのポーリングなど、すべてのポーリングがスピンロックであるとは限りません。
また、ポーリングは本質的に悪いことではありません。ポーリングの期間が非常に短いと、割り込みの使用に必要な高価なコンテキストシフトを回避できます。もちろん、特に低レベルでは、ポーリングの実装が簡単で、メンテナンスが容易になることもあります。いつものように、絶対値はひどいものなので、オプションを盲目的に使用したり破棄したりするのではなく、ニーズに合わせて適切なパフォーマンス/複雑さのトレードオフを与える方法を使用する必要があります。
違いは、スピンロックは(できれば)適切な状況でのみ使用され、これらの状況では非常に効率的であるということです。
リソースが非常に短い時間しかロックされないと予想される場合、たとえばロックが変数の更新のみに使用される場合、スピンロックを使用します。スピンロックは最大速度でロックをポーリングしますが、マイクロ秒未満であることが望ましいです。通常のミューテックスはOS呼び出しで必要になります。IFロックが唯一の時間のわずかな量のために保持されているOSの呼び出しは時間がかかりますが、その後、スピンロックは、CPU時間のわずかな量を使用しています。しかし、この期待が間違っている場合、スピンロックは非常に非効率的です-1つのCPUで100%のCPU時間を使用しますが、通常のミューテックスはOSに入って戻るための時間しかかかりません。
両方が組み合わされることもあります。スピンロックを短時間実行し、スピンロックが機能しない場合は別の戦略に切り替えます。
過剰なポーリングは、システムリソースを浪費するため、実行すべきではありません。ということになる、それがシステムリソースを無駄にしない場合は、ポーリングで結構です。
たとえば、実際の作業で2%の負荷しか発生しない場合、過度のポーリングによりCPU負荷が100%になります。
ポーリングは以外の目的にも使用できますwhile(!ready)
。たとえば、ユーザーがキーを押したかどうかを定期的にチェックすることを意味します。正常な実装では、最大で15ミリ秒に1回チェックされるため、〜2000万クロックサイクルごとに1回チェックされます。この種のポーリングは、システムリソースを無駄にしないため素晴らしいです。
SpinLockは特別な場合ではありません。SpinLockがあり、1つのスレッドがロックに入り、別のスレッドが待機する必要がある場合、待機中のスレッドがシステムリソースを浪費する場合にのみ、SpinLockが間違った選択になります。待機スレッドは、ロックを取得する前にかなりの時間待機する必要がある場合にのみ、システムリソースを浪費します。
したがって、SpinLockを使用して、ロックを解除する前に数千クロックサイクル以上を必要とするもの(たとえば、JavaScriptをオンザフライでコンパイルして実行する)を保護することは、まさにあなたが述べた理由からです。ただし、適切に実装されたハッシュマップにアクセスするなど、SpinLockを使用して迅速に完了するものを保護すると、待機中のスレッドが2〜3回しかスピンせず、システムリソースを浪費しないためです。