2006 年 1 月 6 日 15 時 24 分

スレッドとオブジェクト指向


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


スレッドとオブジェクト指向の間で悩ましいことがある。
実装上の壁ではないので、大きな悩みではないけれど、
今回は趣味の範囲だし、とことん偏執してみよう。

現在、スレッドはクラスとして実装している。
Thread クラスを継承してスレッドを実装する仕組みだ。
派生クラスは new に引数を渡して作成して実行される。
delete で削除すると、スレッドも強制的に終了される。
Shutdown メソッドで終了の同期を取ることもできる。

今回の場合、listener(L) ソケットを持つスレッドは、
クライアントからの接続を受信すると、
接続を受理して新しいセッション用のソケットを作成し、
新しい session(S) 用のスレッドを作成して実行する。

悩みは、スレッドを作成する時だ。
スレッドを作成するのもスレッドである。
S スレッドを作成するのは L スレッド。これは当たり前。
しかし、ソケットを作成するのはどちらの役割だろうか。

処理の流れから言うと、S ソケットの作成が先である。
L スレッドは L ソケットに Accept し、S ソケットを作成。
そして S スレッドを作成して S ソケットを渡す。
S スレッドは受け取ったソケットを「所有」する。

しかし、自分の設計思想として、new で作成したものは、
作成した者が delete するという考えがある。
多少の例外はあれど、基本はこうである。

そうなるとソケットを作るのは S ということになる。
その場合、先に S スレッドを作成することになり、
S スレッドに L ソケットを渡すことになる。
S スレッドは L ソケットに Accept する。

そうすると、L スレッドは S ソケットに関与せずに済む。
データのカプセル化が一歩進むわけだ。

ただ、こうした場合、スレッドクラス特有の問題がある。
もし L ソケットの Accept で失敗した場合、
S スレッドは直ちに破棄されるだろう。
スレッドの作成・削除は重い処理であるので、
一時的とは言え使わない S スレッドを作成するのは痛い。

さて、どうしたものか。

・S クラスのコンストラクタを private にし、
 ファクトリメソッドを追加して
 そこで S ソケット作成⇒S スレッド作成の順に実行。

 ⇒new で生成できないので美しくない。
  (全クラスをファクトリメソッド式にするか?)

・Thread クラスに遅延初期化機能を付け、
 派生クラスはコンストラクタを呼び出した後、
 必ずそれを呼び出すように義務付ける。

 ⇒言語規則上でメソッドの呼び出しを強制できないので、
  呼び出さなくてもコンパイルが通ってしまう。
  もし呼び出さない場合スレッドが作成されないので、
  誤動作の原因となりそう。

・S スレッドを直接 Thread から派生させず、
 Thread から派生したクラスをメンバとして持たせ、
 コンストラクタが完全に終わった後で、
 Thread から派生したクラスのインスタンスを作成する。

 ⇒薄いラッパのようなクラスが追加されてしまい、
  クラス階層が深くなる上に可読性が低下してしまう。

う~む。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.