C++ で Thread-Per-Message パターン

Thread-Per-Mesasge パターンとは時間を要する処理要求に対し、一つ一つスレッドを割り当てる事で応答速度の向上を目的とするパターンです.

例えば以下は時間のかかるファイル保存の処理に Thread-Per-Message を適用した例です.

ここではダミーで標準出力へ出すようにしていますが、 Helper は処理の本体であるファイル保存を行うクラスで Host は client からの要求を受け、処理を行うスレッドを起動するクラスです.  スレッドはインスタンス化と同時に detach され、Host とは完全非同期に処理を実行します.(上記のような簡単な例だと Helper を利用するのが大げさに感じてしまいますが、本来のパターンに忠実に従い上では Helper を定義しています)

さてこの Thread-Per-Message パターンですが、実は使い所が大変難しいパターンだと思います.  なぜ難しいかと言うと スレッドは生成と同時に detach されて生成元のあずかり知らないところで動作を行うため、生成元で処理の終了やエラーの発生を感知できないからです.

では逆にどんな処理なら問題無いかと言うと

(1) 絶対エラーが発生しない (もしくは発生しても問題ないと) と分かっている単純な処理.
(2) deadlock 等が発生せず、一定の時間で終了することが保証されている処理.
(3) スレッドで実行される処理が非同期に動作するプログラムとして高い独立性を持っており、エラー処理等を完全に自己で完結出来る場合.

の場合のどれかに当てはまる場合でしょう.  (1) は言うまでも無いと思いますが、(2) の場合 deadlock を起こしたスレッドが開放されない事で徐々に OS のリソースを食いつぶして行き、最終的に処理速度の低下やスレッド生成の失敗等につながる恐れがあります.  (3) は Apache 等の Web サーバーがリクエストを捌く際に行う処理がまさにそれです (Apache の場合はリクエスト毎にスレッドでは無くプロセスを起動するので Process-Per-Message というのが正しいですが..)

というわけで今回取り上げたファイルに保存すると言う例も、ログファイルなどの「まぁ、問題が起こったら保存されなくてもしょうがないよね」というような用途以外で使用するのは適切ではありませんのでご注意を.

C++ でマルチスレッドデザインパターン

 

広告

C++ で Balking パターン

Balking パターンとは「オブジェクトに対しての処理要求に対し、オブジェクトが特定の状態にある場合にのみ処理を行う(そうでない場合は何もしないで抜ける)」というパターンです。

例えば GUI システムでは多くの場合 main スレッドが UI のイベントループをハンドルしているため、lock 待ち等で main スレッドが待ち状態に入ると UI がフリーズしてしまいユーザビリティーの観点から好ましくありません。その場合 try lock のような仕組みを利用して確実に lock が取得できる場合のみ lock 取得処理を行う(そうでない場合はイベントループを回し、lock が取得できるようになるまで待つ)と言うことが良く行われます.

上記がここで取り上げた例の擬似コードになります.  パターンの適用例としてはあまり紹介されていないように思いますが、これも一種の Balking パターンだと思います.

C++ でマルチスレッドデザインパターン