本講座も最終回を迎えることになりました。今回は「システム・データベース」という角度からWindows 2000の世界をのぞいてみましょう。

システム・データベースとは何か

 「システム・データベース」からシステムという単語を取り外してみましょう。すると当然「データベース」という,すでに多くの人が慣れ親しんでいる用語が登場します。データベースは一般には,データが格納されている基地という意味を持ちます。基地はそれぞれ固有の構造を持ちますから,個々の基地内のデータを取り出すにはデータを提供する“プロバイダ”が必要です。プロバイダは基地からデータを取り出すだけではなく,データの追加,更新,あるいは削除といった機能を持っています。

 Windows 2000のシステム・データベースは,Windows 2000自身が動作するために必要なデータを格納する基地,と言えるでしょう。Windows 2000システム・データベースの代表格は「レジストリ・データベース」です。通常レジストリと略称されていますが,これを「中央データベース」と呼ぶこともあります。レジストリの内容の一部を図1[拡大表示]に示します。レジストリは,Windowsシステムが持つ,ハードウエア情報,ソフトウエア情報,ユーザー情報などを管理します。レジストリからデータを取り出し,図1のような情報を表示するためには専用のプロバイダが必要になりますが,それにあたるのが「regedt32.exe」というWindows 2000に付属するプログラムです。これから紹介する「プロセス・データベース」「スレッド・データベース」もシステム・データベースの一種です。さっそく見ていきましょう。

スレッド・データベースとスレッド情報

 スレッド・データベースという用語はそれほど使用されるわけではありません。私がこの用語を初めて知ったのは,OS解析の第1人者と言われる,米Compuware NuMegaに勤務するMatt Pietrek氏の「Windows 95システムプログラミング」(ソフトバンクパブリッシング発行)という書籍でした。同氏は,Windows 95がスレッドを管理するために内部で作成しているデータ・ブロックを便宜上スレッド・データベースと命名していました。スレッド・データベースがあれば,当然プロセス・データベースがあります。プロセス・データベースは,前回説明した「プロセス」情報を管理するデータベースです。前回はこのプロセス・データベースから情報を取り出し,画面に表示させたわけです。理論的な説明はこれくらいにして,さっそくサンプルを実行してみましょう。「Sample5_1.vbs」というサンプル・プログラムを実行すると図2[拡大表示]のような画面が表示されます。

 この画面は「Services.exe」のプロセスが内部で生成したすべてのスレッドの情報を収集し,表示しています。実は,このサンプル・プログラムは前回講座で使用した「Sample4_2.vbs」というサンプル・プログラムが収集する情報を応用しているにすぎません。ポイントは,“すべてのスレッドは自分が所属しているプロセスにアクセスするための方法を知っている”ということです。前回のサンプル・プログラムを実行させると分かるように,プロセスは使用できるメモリー資源や実行優先度などの情報を持っています。スレッドは自分が所属するプロセスの情報を使って動作するのが基本です。このため,必要に応じてプロセス・データベースを参照します。データベースを参照する際は,「プロセス・ハンドル」という情報が使われます。

 プロセス・ハンドルは,Windows 2000内部で動作している個々のプロセスを識別するための情報です。この情報はWindows 2000が作成し,個々のプロセスに割り当てます。つまり,プロセス情報はWindows 2000がプロセスを管理するために内部で使用するシステム情報といえます。このプロセス・ハンドルというシステム情報は,ご想像のように,すでに説明したプロセス・データベースに格納されます。データベースという角度から見れば,プロセス・ハンドルは,特定のプロセスの情報を保持している,データベース内の位置を知らせるデータであると考えておくとよいでしょう。

 図2を具体的に説明すると,Services.exeのプロセスは,236というプロセス・ハンドルを割り当てられています。一方スレッドは,プロセスから作成されますから,作成されるときに,プロセスの一部情報を引き継ぐことになります。上の画面では,ベース実行優先度と所属するプロセス・ハンドルという情報を引き継いでいます。

 少し視点を変えて,Windows 2000側からプロセスとスレッドの関係を整理してみましょう。Services.exeプロセスからスレッド生成要求が出されると,Windows 2000は新たに生成するスレッド用のスレッド・データベースを作成します。作成後,すでに作成してあるServices.exeプロセス・データベースの一部情報を,今作成したばかりのスレッド・データベースにコピーします。実行優先度やプロセス・ハンドルなどをコピーするわけです。これで,スレッドは自分が所属するプロセスを認識することができます。大雑把な整理ですが,概要説明としてはこれで十分でしょう。

 それではもう一度図2を見てみましょう。検出されたスレッド個数は27と報告されていますから,Services.exeのプロセスは27個のスレッドを内部で作成していることになります。27個のスレッドすべてが保持するプロセス・ハンドルを見てください。すべて同じ値になっているはずです(この画面の場合236)。この値はすでに触れたように,Windows 2000がServices.exeプロセスに割り当てた値です。スレッドは自分を作成したプロセス,つまり,所属先プロセスの情報を持っているのです。ここまで話が進行してくると,次のような疑問を持つ人がいるでしょう。

“Services.exeプロセスのように,たった1個のプロセスが多数のスレッドを内部で作成しているのであれば,Windows 2000には無数に近いスレッドが作成されてしまうことになるが,それで大丈夫なのだろうか?”

 このような疑問が発生するのは当然です。スレッド情報はメモリー内に作成され,多少の時間もかかり,当然メモリーも消費されます。この意味では,作成されるスレッド個数を把握することは重要な意味を持ちます。

 ここで第2サンプル・プログラムである「timeconsumer.vbs」を紹介しましょう。このサンプル・プログラムを実行すると,図3[拡大表示]のような画面が表示されます。

 ご覧のように,私のWindows 2000 Professional環境では278個のスレッドが生成されていています。Windows 2000 Server環境になるとどのくらいになるのでしょう。ネットワーク環境をご利用できる方はぜひ試してください。このサンプル・プログラムはSample5_1.vbsをほんのちょっと変更しただけですが,処理を完了するために要する時間が長く,作成されるファイルのサイズも膨大になります。実際に実行してみると,私がこのサンプル・プログラムに「timeconsumer(時間食い)」という名前を付けている理由が分かるはずです。

 これまでの説明からプロセスとスレッドの関係はお分かりいただけたと思いますが,多くの人は,次のような疑問を持つことでしょう。

“Windows 2000は,200を超えるスレッドの実行状態をどのように管理しているのだろう。”

 すでに前の講座で触れているように,プロセス個数もスレッドの個数も時々刻々変化します。Windows 2000では常に新しいプロセスとスレッドが誕生しては,その寿命を終えています。それでは「sample5_1.vbs」を実行すると作成される「sample5_1.txt」をもう一度見ていただきましょう。

 この2個のスレッド情報を比較してみてください。ベース優先度はプロセスから引き継いだ値ですから,いずれのスレッドでも同じです。しかし,実行優先度は異なっています。この場合,実行優先度として10を持つスレッドの方が9を持つスレッドより優先実行されます。微妙な違いですが,Windows 2000はこのような値を調整することにより,スレッドを管理しているのです。

 「スレッド実行状態」はスレッドが現在置かれている立場を示しています。これらの2つのスレッドは5という値を持っていますが,これは「待ち」状態に入っていることを示しています。その他の状態としては,実行状態,移行状態,スタンバイ状態,初期化状態,準備完了状態,不明状態などがあります。そして,待ち状態に入っている理由が,「この状態にある理由」にある15という値で示されています。15というのは,何らかのイベントが発生するのを待っていることを示しています。これ以外の理由としては,空きページ待ち,ユーザーからの要求待ち,ページ・アウト待ち,実行遅延などがあります。このようなスレッド状態やその理由を知りたい方は,「初心者のためのWindows 2000入門」第4回を参照してください。

 それでは本講座最後のサンプル・プログラムSample5_2.vbsを紹介することにします。このプログラムを実行すると図4[拡大表示]のような情報が表示されます。

 ご覧のように,このサンプル・プログラムは,特定のディレクトリにファイルを作成し,その格納位置情報,OS情報,コンピュータ情報などを収集し,表示します。ビルド番号やコンピュータの製造元名,現在ログインしているネットワーク・ドメイン名などが分かります。ファイルを作成するディレクトリ情報をどのように探し出しているかに興味を示す人もいるでしょう。ここでは説明しませんから,ぜひソースコードを検討してみてください。ソースコード内部では特に変わったテクニックは一切使ってません。「やる気」があれば理解可能なです。ご検討をお祈りいたします。それでは今回の内容と本講座全体のまとめに入ります。

まとめ

 今回取り出した情報は,Windows 2000の世界でも,どちらかといえばシステムよりの情報です。ソースコードを検討すると分かりますが,コーディング方法には一定の決まりがあります。その決まりさえ学習してしまえば,必要な情報を効率的に取り出すことができます。本講座でご紹介したコンポーネントやその機能はまさに氷山の一角にすぎません。Windows 2000の世界は,簡単に再利用できるCOMコンポーネントを多数持っています。むしろ,Windows 2000の世界はコンポーネントで構成されているといっても過言ではないのです。Windows 2000は確かに複雑なOSですが,本講座で示したように,私たちが必要と判断した再利用部品のみを選択し,それを自由に使うことができるようになっています。

 今回は,プロセスとスレッドの関係をシステム・データベースという角度から説明し,Windows 2000のサービスとの関係付けも行いました。私がServices.exeを取り上げたのは,それなりの理由があるからなのです。このServices.exeこそWindows 2000の中核プロセスなのです。もちろん,それ以外にも重要なプロセスがあります。例えば,svchost.exeプロセスやdllhost.exeプロセスなどです。これらは必要に応じて多数のスレッドを内部で作成します。多くの人はそのようなWindows 2000の内部事情を知らないでしょう。しかし,システムのパフォーマンスが著しく低下したとき,突如メモリーが不足する事態に陥ったときなどは,このような背景知識をもっていると,問題を引き起こしているプロセスやスレッドを特定できるため,解決の近道となるのです。

 Services.exeを知ることはある意味で,Windows 2000の世界を知ることです。Sample5_1.vbsの実行画面は一見すると単純そうに見えます。しかし,Windows 2000を使用する上での貴重なデータとなるはずです。Windows 2000は確かに複雑なOSでしょうが,便利な機能を多数内蔵しているOSでもあります。便利な機能は使わなければ損です。そのためには,多少努力が要求されても,Windows 2000の世界を理解する必要があります。本講座が皆様のWindows 2000世界を理解するための一助になれば,筆者としてはこの上ない喜びです。またどこかでお会いいたしましょう。