1. ホーム
  2. c

[解決済み] pthread_cond_wait で spurious wakeup が発生するのはなぜですか?

2022-04-24 05:43:15

質問

マニュアルページを引用します。

<ブロッククオート

条件変数を使用する場合、各条件の待機に関連する共有変数を含むブール述語が常に存在し、スレッドが続行すべき場合に真となります。pthread_cond_timedwait() や pthread_cond_wait() 関数から偽のウェイクアップが発生する可能性があります。pthread_cond_timedwait() または pthread_cond_wait() からの戻りは、この述語の値について何も暗示しないので、そのような戻りの際に述語は再評価されるべきである。

だから pthread_cond_wait は、シグナルを発していなくても戻ることができます。少なくとも一見したところ、それはかなり非道なことのように思えます。ランダムに間違った値を返す関数や、実際に適切な return 文に到達する前にランダムに返す関数のようなものでしょう。大きなバグのように思える。しかし、これを修正するのではなく、manページで文書化することを選んだという事実は、以下のような正当な理由があることを示しているように思えます。 pthread_cond_wait はスプリアスを起こして終了します。おそらく、その仕組みに何か本質的なものがあって、どうしようもないのだろう。問題は、それが何かということです。

なぜ pthread_cond_wait はスプリアスを返すのでしょうか?なぜ、適切にシグナルが送られたときだけ目覚めることを保証できないのでしょうか?どなたか、その偽りの動作の理由を説明していただけませんか?

解決方法は?

でDavid R. Butenhofが以下のような説明をしています。 POSIXスレッドでプログラミング" (p. 80):

<ブロッククオート

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

以下では comp.programming.threadsの議論 と、設計の背景にある考え方について説明しています。

Patrick Doyle さんが書き込みました。
> 記事の中で、Tom Payne が書いています。
> >Kaz Kylheku さんが書き込みました。
> >です。というのも、実装上、挿入を避けられない場合があるからです。
> >: これらの偽のウェイクアップを防ぐには、コストがかかるかもしれません。

> >しかし、なぜでしょうか? なぜ、こんなに難しいのでしょうか? 例えば、以下のような話でしょうか。
> >信号が到着した瞬間に待ち時間がタイムアウトするような状況でしょうか?

> pthreadsの設計者はこんなロジックを使っていたんでしょうかね。
条件変数を使用する場合は、終了時に条件を確認する必要があります。
を許可しても、それ以上の負担はありません。
偽のウェイクアップを許可することは可能であり、また、偽のウェイクアップを許可することは可能である。
ウェイクアップは実装を高速化する可能性があり、それは私たちの助けになります。
gt;許可する。

> 特定の実装を想定していなかったのかもしれません。

実は、押しが足りないだけで、全然外れていませんよ。

その意図は、述語ループを要求することで、正しい/堅牢なコードを強制することでした。これは 
の中で、証明可能な正しさを持つ学術的なコンティンジェントによって推進された。
しかし、その意図に反対する人はいなかったと思います。
その意味を理解した上で 

私たちはその意図に沿い、いくつかのレベルで正当化しました。まず、1つ目は 
ループの使用は、アプリケーションを不完全なものから保護します。
コーディングの実践。2つ目は、抽象的に想像することが難しくなかったからです。
この要件を利用して、マシンと実装コードを改善することができます。
平均的な条件下での待ち時間を最適化することで、その性能を向上させることができます。
同期機構 
/------------------[ [email protected] ]------------------\ 
| コンパックコンピュータ株式会社 POSIXスレッドアーキテクト 
| 私の本: http://www.awl.com/cseng/titles/0-201-63392-2/ |。
\-----╱[ http://home.earthlink.net/~anneart/family/dave.html ]-----/