待ち合わせというのは回数をできるだけ少なく、また待つ時間も短くできるならそうした方が良いに決まっています。
当然のことです。
OSの同期システムコールを使って待ち合わせについて考えると、ポーリングでの待ち合わせで無駄になるCPUパワーは、
ポーリングの回数×ポーリングで消費されるCPUパワー
ですよね。
ちょっと考えればわかることですが、ポーリングではCPU負荷が小さいほどCPUパワーが無駄になります。
CPU負荷が小さいほど、待ってる間にポーリングするプロセスやタスクにCPUが回ってくる確率が高くなるため、トータルのポーリング回数が増えるからです。ポーリングは必要な処理なのでしょうが、本来やるべき仕事ではなくオーバーヘッドですので無駄というわけです。
これは非同期の待ち合わせを安易に実装してはいけない理由のひとつの例です。
ポーリングとしては、外部IOの監視や、メッセージ通信(メールスロット)の定期的な監視があります。IOは本来割り込みで処理すべきですが、なかなかそうもいかない場合もあります。しかしメッセージ通信については、ほとんどのOSで受信待ちの機能が提供されているにもかかわらず、非ブロック型の到着メッセージ数をポーリングするシステムコールとSleep関数が重宝がられます。
定石としては、メッセージの待ち行列をポーリングするのではなく、計数セマフォを組み合わせて送信側と受信側で待ち合わせを構成するべきなかもしれません。
教科書どおりの、生産者-消費者問題ですら、のぞましい実装のサンプルはどこにもありません。
望ましいと書いたのは、素朴な実装では以下ような点について考慮されていないために、堅牢性が全く無いからです。
- 待ち行列のあふれに対応できない
- 待ちぼうけ(送信側が気絶または死亡)に対応できない
ようするに現実的なエラー処理を考えると、CPUパワーを無駄にしてでもポーリングで再発明するしかないというわけです。
現実的なエラー処理とは、タイムアウトや自前のフロー制御です。おそらくOSメーカはメッセージの待ち行列が有限であることへの対処はユーザプログラマが解決するべき問題であり、輻輳制御問題ではないと主張しているのでしょう。
コメント