偽のウェイクアップの説明は、修正するだけの価値のないバグのように聞こえますが、そうですか?


30

スプリアスウェイクアップに関するウィキペディアの記事によると

「スレッドは、条件変数にシグナルを送っていなくても、待機状態から目覚めさせることができます」。

私はこの「機能」について知っていましたが、同じ記事で実際に何がそれを引き起こしたのかは知りませんでした

「スプリアスウェイクアップは奇妙に聞こえるかもしれませんが、一部のマルチプロセッサシステムでは、コンディションウェイクアップを完全に予測可能にすると、すべてのコンディション変数操作が大幅に遅くなる可能性があります。」

修正する価値のないバグのように聞こえますが、そうですか?


1
関連:「なぜpthread_cond_waitのは、スプリアスウェイクアップがありますか?」、stackoverflow.com/questions/8594591/...
フロリアン・カステラーヌ

回答:


39

スプリアスウェイクアップのTL; DR仮定(「契約」)は、スレッドシェラーの現実的に堅牢な実装を可能にするために行われた、賢明なアーキテクチャ上の決定です。

「パフォーマンスに関する考慮事項」はここでは無関係であり、これらは公開された信頼できる参考文献で述べたために広まった誤解にすぎません。(信頼できる参照にはエラーがあるかもしれません- ガリレオ・ガリレイに聞いてください) Wikipediaの記事は引用されたメモへの参照を保持しています。

スプリアスウェイクアップの概念を導入するより説得力のある理由は、SOのこの回答で提供されており、その記事の(以前のバージョン)で提供された追加の詳細に基づいています。

スプリアスウェイクアップに関する Wikipediaの記事には、次のようなヒントがあります。

pthread_cond_wait()Linux の機能は、futexシステムコールを使用して実装されます。Linux上の各ブロッキングシステムコールはEINTR、プロセスがシグナルを受信すると突然戻ります。... システムコールのpthread_cond_wait()外にあったわずかな時間で実際のウェイクアップを見逃す可能性があるため、待機を再開できませんfutex...

考えてみてください...他のコードと同様に、スレッドスケジューラは、基盤となるハードウェア/ソフトウェアで異常が発生したために一時的なブラックアウトが発生する場合があります。もちろん、これが可能な限りまれに発生するように注意する必要がありますが、100%堅牢なソフトウェアなどはないため、これ発生すると想定し、スケジューラがこれを検出した場合にグレースフルリカバリに注意することは合理的です(例:欠落しているハートビートを観察することにより)。

さて、ブラックアウト中に待機中のスレッドに通知するためのシグナルを逃す可能性があることを考慮して、スケジューラはどのように回復できますか?スケジューラが何もしないと、「不運な」スレッドがハングし、永遠に待機します-これを避けるために、スケジューラはすべての待機スレッドにシグナルを送信します。

このため、待機中のスレッドに理由なく通知できる「契約」を確立する必要があります。正確には、スケジューラブラックアウトという理由がありますが、スレッドは(正当な理由で)スケジューラの内部実装の詳細を無視するように設計されているため、この理由は「スプリアス」として提示する方が適切です。


スレッドの観点からは、これはややポステルの法則(別名ロバスト性原理)に似ています。

あなたがすることにおいて保守的であり、他人から受け入れることにおいて寛大であること

スプリアスウェイクアップの仮定は、スレッドが行うことで保守的になります:他のスレッドに通知するときに条件を設定し、受け入れることでリベラルになります:待機から戻ったときに条件を確認し、まだない場合は待機を繰り返します。


10
うーん...ポステルの法則... HTMLやあらゆる種類のWebテクノロジーが非常に多くのがらくたを投げかけている理由(たとえば、HTMLが悪いタグのネストを受け入れているなど)。それはさておき、良い答えです。
トーマスエディング14年

3
Postelの法則により、何年もの間多くのバグが捕捉されないのは、関数が間違った出力を返したとしても、アプリはまだ動作しているようだからです!史上最高の発明。
パセリエ

2
@Pacerier:間違った出力を返す関数はポステルの法則に従っていません(保守的な部分)。
-YvesgereY

@Pacerier:OTOH、バグを早期に発見できるように他のコンポーネントを厳格に要求することは興味深い位置であり、「Fail Fast」の原則と「Contract Based」の設計の誤りです。
YvesgereY

1

とにかく、呼び出し側のコードは競合状態に対処するために同じ処理(状態の確認)を使用する必要があるため、修正する価値はありません。

次のように要約する2つの問題に対する1つの扱い。

スプリアスウェイクアップ:条件が確立される前に待機スレッドがスケジュールされます。
強制オーバースリープ:条件が再度改ざんされた後、待機スレッドがスケジュールされます。

後者が発生する可能性があるため、一部の人は契約に偽のウェイクアップを導入するまで進みました。

  • 述語ループを要求することにより、優れた慣行を実施します。
  • スケジューラの実装にある程度の自由度を与える(@gnatが指摘した緊急復旧オプションを含む)。

SOリファレンス


私はこれを+1したいが、誰かが意図的に偽のウェイクアップを導入して、発信者に強制的なスリープ状態に対処するための述語ループを追加させるという考えのために。それは考えられないことです。
1

「意図は、述語ループを要求することにより、正しい/堅牢なコードを強制することでした。」提供されたリンクを参照してください。
YvesgereY
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.