COM+には,実行の同期化機能がある。同期化を検討すべきなのは,主にマルチスレッドで動作させる可能性のあるCOMコンポーネントを開発するときである。Visual BasicでCOMコンポーネントを開発する場合,シングルスレッドアパートメントモデル(STA)のCOMコンポーネントしか作ることができないので,基本的にCOM+の同期化についてはあまり考える必要はない。しかし,ほかの言語でCOMコンポーネントを作るときの参考になるので,ここで簡単に同期化機能について説明しておく。
●アパートメントモデル
まずはじめに,COMコンポーネントのアパートメントモデルについて説明する。COMコンポーネントは,大きくシングルスレッドアパートメントモデル(STA)とマルチスレッドアパートメントモデル(MTA)に分けることができる。
COMオブジェクトは,必ずアパートと呼ばれる単位のなかで実行される(Fig.5-36)。シングルスレッドアパートメントモデルの場合には,1つのアパートに含まれているCOMオブジェクトは同時に実行されないことが保証される。具体的には,外部からメソッドを呼び出す要求をキューに格納する仕組みがアパートメントの境界に用意されていて,外部からのメソッドの呼び出しに対しては,必ずこのキューを経由する。メソッドを呼び出す要求はキューに溜められたあと,順に取り出され,実際にメソッドが呼び出される。一方のマルチスレッドアパートメントモデルの場合には,アパートに入っているCOMオブジェクトは複数のスレッドによって同時に呼び出される可能性がある。そのため,マルチスレッドアパートメントモデルをサポートするCOMオブジェクトは,メソッドの呼び出しを同時に受けても,問題なく動作するような仕組みを備えていなければならない(そのようにプログラムを実装することを「スレッドセーフにする」と呼ぶ)。
Fig.5-36 アパートメントモデル
アパートメントは,COMクライアントごと(より正確にいえばプロセスごと)に作られる。つまり,シングルスレッドアパートメントモデルであれば,すべてのCOMクライアントが1つのキューを共有するというわけではなく,COMクライアントごとに別々のキューが作られる(さらに1つのCOMクライアントのなかに複数のアパートメントを作ることもできる)。つまり,COMクライアントが違えば,キューも違うことになる。そのため,ある1つのCOMコンポーネントから実体化された複数のCOMオブジェクトを別々のCOMクライアントから利用する場合,それらのCOMオブジェクトは同時に実行される。
●同期化の必要性
さて,マルチスレッドアパートメントモデルの場合には,複数のスレッドから同時に呼び出される可能性があるので,メソッドが同時に呼び出されても問題なく動作するような仕組みを備える必要がある。これは,比較的大変な作業である。というのは,ちょっとしたタイミングの違いによって誤動作することが考えられるからである。
たとえば,List 5-7に示すgetCountというメソッドを備えたCOMコンポーネントがあるとする。
List 5-7には記されていないが,もしCOMオブジェクトを実体化するときにグローバル変数Counterが0に設定されているとすれば,getCountメソッドを呼び出すたびに,1,2,3,……という数値が戻るだろう。
しかし,getCountメソッドが複数のスレッドから呼び出された場合,その順序によっては,必ずしも1,2,3,……という数値が戻るとは限らない(Fig.5-37)。
Fig.5-37 複数のスレッドから呼び出された場合
このような問題を避けるには,同時にアクセスできないようなロック機構を備えるなど,少々厄介な処理が必要になる(具体的には,Win32APIの「ミューテックス」と呼ばれる機構を使うのが一般的である)。
●COM+における同期化のサポート
以上で説明したように,マルチスレッド動作に対応させるには,プログラム側での比較的高度なテクニックが必要となり,なかなか難しい。しかし,マルチスレッド動作にさせると,同時に複数の処理を実行できることから,その魅力は捨てがたい。そこでサポートされているのが,COM+の同期化機能である。COM+の同期化は,COMコンポーネントのプロパティにおける[同時実行]ページで設定できる(Fig.5-38)。
Fig.5-38 [同時実行]ページ
各オプションの意味は,次のとおりである。
- [使用不可]
- 同期化機能を無効にする。
- [未サポート]
- 同期化機能は使わない。
- [サポート]
- このCOMオブジェクトを呼び出したCOMオブジェクトが同期化をサポートしていたら,同期化する。
- [必要]
- 同期化をサポートする。このCOMオブジェクトを呼び出したCOMオブジェクトが同期化をサポートしていたら,その同期化のグループに参加する。
- [新しく必要]
- 新しい同期化のグループを作る。
同期化もトランザクションと同様に,1つのグループを作る。このグループのことを「アクティビティ」と呼ぶ。同じアクティビティに格納されたCOMオブジェクトは,シングルスレッドアパートメントモデルのように,キューを経由された呼び出しとなり,同時に複数のスレッドから呼び出されないことが保証される(Fig.5-39)。この機能によって,開発者がマルチスレッドアパートメントモデルのCOMオブジェクトを構築するのが容易になる。
Fig.5-39 アクティビティ
以上のように,COM+の同期化機能は,マルチスレッドアパートメントモデルのときに利用されるものである。シングルスレッドアパートメントモデルの場合には,アパートの範囲とアクティビティの範囲が一致するため,特に何も考えなくてよい。Visual Basicはシングルスレッドアパートメントモデルしかサポートしなしため,Visual Basicで開発したCOMコンポーネントの場合には,[同時実行]ページのオプションは[未サポート]でよい。
ただし,ジャストインタイムアクティベータを有効にした場合には,同期化のサポートを[必要]または[新しく必要]以外に設定することはできない。また,トランザクション機能を使っている場合には,同期化のサポートを[必要]以外に設定することはできない。
なぜなら,トランザクションの実行中に別のスレッドが割り込んでしまうと,「トランザクションとは一連の操作をするものであり,そのあいだにはほかの処理が割り込んではならない」という原則が崩れるからである。
|