第3回 プロセスとスレッド:Windows OS入門(2/2 ページ)
OSの一番核となる機能と言えばプロセス管理。Windows OSの内部ではプロセスやスレッドはどのように動作しているのか、GUIアプリケーションのパフォーマンスなどを改善する優先度/クォンタムブースト、マルチコアCPUの性能を引き出すスレッドスケジューリングやアフィニティ設定などについて解説。
スレッドのスケジューリングと状態遷移
スレッドが作成されたら、プロセスやスレッドのスケジューラー(スレッドディスパッチャー)によって実行するCPUコアを選定し、その実行待ち行列(キュー)へスレッドが登録される。CPUのコアごとにスレッドの実行待ちキューがあり(さらに、優先度別にもキューが分かれている)、準備ができたスレッドから順に実行が開始される。実行を開始してから、あらかじめ決められた時間が経過すると次のスレッドの実行へ移る。
スレッドの状態遷移図を次に示しておく。CPUコアの実行待ち行例に登録されたスレッドは、CPUの利用権が実際に得られたら、そのCPU上で実行を開始する。タイムスライス時間(クォンタムタイム。詳細は後述)が経過すると、他のスレッドに制御を渡すか、他に実行待ちのスレッドがなければ引き続き実行される。スレッドが終了するか、I/O待ち、イベント待ちなどで実行できなくなった場合も実行を中断し、他のスレッドに実行権を渡すことになる。
スレッドの状態遷移図
スレッドの状態遷移。各状態に付けられている数字は、パフォーマンスモニターの「Thread」オブジェクトの「Thread State」で表示される状態番号。
(0)スレッドの作成が完了するまではこの状態になる。
(1)実行準備が整ったスレッドはこの「準備完了」状態になってCPUのキューに入れられ、スケジューラーによるディスパッチを待つ。
(2)これは実行中の状態。タイムスライス時間(クォンタムタイム。詳細は後述)が経過するか、自発的にウェイト状態へ入る、もしくは、より優先度の高い処理などによって割り込まれたら(プリエンプトされたら)、準備完了か待機状態へ移行する。
(3)「スタンバイ」は、実行待ちキューの先頭にあって、次にCPUの実行権を与えられる予定のスレッドが入っている。
(4)スレッドが終了するとこの「終了」状態に入り、スレッドに関連するリソースの解放などの処理を行う。
(5)実行中のスレッドが自発的にウェイトしたり、I/O待ちや他のプロセスからのウェイト要求、スワップアウトなどによって実行が中断すると、スレッドはこの「待機」状態に入る。
(6)「トランジション 」状態では、スワップアウトしていたページがスワップインされるのを待ったり、実行に必要なリソースが利用可能になるのを待ったりする。
(7)「遅延レディ」は、実行するCPUは決まっているが、まだスケジューリングされていない状態のスレッドを表す。システム全体でスケジューリングするのではなく、CPUごとに限定することによって、ディスパッチャーデーターベース(スレッドの実行待ちキューの管理データーベース)を操作するために、システムレベルのロック(排他制御)を使う必要がなくなる。CPUレベルのロックでよいので、マルチプロセッサーシステムにおけるスケーラビリティが向上する。「遅延レディ」はWindows Server 2003から実装されている。
一度実行されたスレッドが待ち状態になった後でまた実行される場合、ディスパッチャーはなるべく同じCPUコアにスレッドを割り当てるようにする。もしCPUコア間をまたがってスレッドを切り替えると、CPUキャッシュのヒット率などが下がり、パフォーマンスが低下するからだ。ハイパースレッド(Simultaneous Multithreading:SMTともいう)やNUMAのようなマルチプロセッサー環境でも、なるべく同じコアや同じブロック内でスケジューリングするように最適化されている。
プロセスとスレッドの優先度
Windows OSではプロセスやスレッドに32段階の優先度(0〜31)を設定できる。ユーザーが一般に作成するアプリケーションの優先度は「通常」である。だが用途によってはもっと高くして優先的に処理させたり、逆にフォアグラウンドのアプリケーションに影響を与えないように、もっと優先度を下げることもできる。
プロセスの優先度の確認と変更
タスクマネージャーでは、プロセスの優先度を6段階で設定できる。
(1)優先度を確認・変更するには、プロセス名を右クリックしてこれを選択する。
(2)6段階に設定できる。コマンドプロンプト上で「start /high 〜」のようにしても、優先度を変更できる。
タスクマネージャーの画面では優先度は6段階しか設定できないが、これらは実際には0〜31のいずれかの優先度の数値に変換されて設定される。0が最低優先度、31が最高優先度である。
優先度 | 基本優先度クラス |
---|---|
リアルタイム | 24(22〜26) |
高 | 13(11〜15) |
通常以上 | 10(8〜12) |
通常 | 8(6〜10) |
通常以下 | 6(4〜8) |
低 | 4(2〜6) |
Windows OSの基本優先度クラス Windows OSには0〜31の32レベルの優先度があるが、APIなどではこの6つの基本的な優先度クラスで設定する。ここで設定した優先度がプロセスの基本優先度となる。プロセスに属するスレッドには、プロセスの基本優先度が初期優先度として割り当てられる。動作中のプロセスやスレッドの優先度は、この基本優先度をベースにして、状況に応じていくらか上下するように制御される。 |
優先度設定にはこの表の通り6段階あるが、これはプロセスの「基本優先度クラス」として扱われる。ここで設定した優先度はスレッドの初期基本優先度として引き継がれるが、その後のスレッド優先度はプロセスやスレッドのスケジューラーによっていくらか上下するように制御される。
スレッドの優先度ブースト
スレッドの優先度は、基本的には最初に設定された「プロセスの基本優先度クラス」を引き継ぐ。その一方で、状況によっては優先度を一時的に上げる「優先度ブースト」という機能も持っている。次のような場合に優先度を上げて、アプリケーションの応答性などを向上させている。
- デバイスのI/O動作完了時
- スケジューラーなどで特定のイベントが起こったとき
- GUIの入力時
- イベントやセマフォのリソース待ちなどで長時間待たされている場合
- 準備完了状態で長く待たされている場合
いったん上がった優先度はしばらくすると元に戻るように制御されているので、特定のアプリケーションだけがずっと優先的に動作することはない。
スレッドのクォンタムタイム
システム上に複数の実行可能なスレッドがある場合、スケジューラーはある短い時間間隔で区切ってスレッドをCPUに順に割り当てたり、切り替えたりしながら実行する。スレッドが連続して実行可能な時間を「クォンタムタイム(quantum time)」と呼ぶ。この時間はWindows OSのバージョンやシステムの構成などによって変わる。以下に、クォンタムタイムの割り当て方法を変更する設定画面を示しておく。
スケジューリング方法の設定変更項目
システムのプロパティ画面で[詳細設定]タブを開き、「パフォーマンス」グループにある[設定]ボタンをクリックすると、この「パフォーマンス オプション」画面が表示される。この設定を変更すると、プロセスやスレッドのスケジューリングアルゴリズムが少し変更される。
(1)このタブを選択する。
(2)クライントWindowsでは、デフォルトではこちらが選択されている。
(3)サーバーWindowsでは、デフォルトではこちらが選択されている。
クライアントWindows OSではデフォルトで「プログラム」という方が選択されている。こちらを選択すると、GUIの応答性などを向上させるためにクォンタムタイムが短くなり、さらに場合によってはフォアグラウンドのプロセスの方がバックグラウンドのプロセスよりもクォンタムタイムが長くなるように(つまり、フォアグラウンドアプリケーションの応答性が向上するように)制御される。これを「クォンタムブースト」と言う。
サーバーWindows OSのデフォルト設定では「バックグラウンド サービス」という方が選択されている。こちらを選択すると、クォンタムタイムは「プログラム」の場合の6倍(「プログラム」と比較した場合の相対値)の固定長となり、全てのプロセス(スレッド)が安定して同じように動作するようになる(GUI操作などによって、バックグラウンドで動作しているプログラムがあまり影響を受けないようにするため)。
スレッドのアフィニティ(関係)の設定
スレッドは、デフォルトではCPUのどのコア上でも動作するようになっており、必要に応じて空いているコアへ自動的に割り当てられるようになっている。だが特定のプロセス/スレッドが全コアを占有して、他のプロセスが動作できなくなることを防ぐために、利用可能なコアを制限することもできる。どのプロセス(スレッド)がどのCPU上で実行可能かという属性のことを「アフィニティ(affinity)」と言い、実行可能なコアのリストを「アフィニティマスク(affinity mask)」という。タスクマネージャーで操作する場合は、「プロセス」タブでプロセス名を右クリックし、ポップアップメニューから「関係の設定」を実行すると、特定のCPUコアのみを利用するように制限できる。
プロセッサーアフィニティの設定
プロセス(スレッド)がどのCPUコアを使うかという属性を「プロセッサーアフィニティ」と言う。デフォルトでは、全てのプロセスは、全てのコアを利用可能となっているが、これを制限することもできる。「CPUバウンドなプロセス(CPUを非常に多く使うプロセス)」に対してアフィニティマスクを設定しておくと、ほかのアプリケーションの応答性が低下するのを防ぐことができる。
(1)プロセッサーアフィニティを確認・設定するには、プロセス名を右クリックして[関係の設定]を選択する。
(2)チェックボックスがオンになっているコア上でのみ実行されるようになる。コマンドプロンプト上で「start /affinity 0x3f <コマンド文字列>」のようにしても、プロセッサーアフィニティを変更できる。
代表的なWindowsのプロセス
Windows OSが起動すると最初に「System」という名前のプロセスが実行を開始し、これが全てのルートとなって、その他のシステムプロセスやユーザープロセスなどを起動するようになっている。以下に、タスクマネージャー画面などで見ることの多い、Windows OSでよく使われているシステムプロセスの概要についてまとめておく。
プロセス名 | 意味 |
---|---|
conhost.exe | コンソールウィンドウホスト。cmd.exe実行用のホストプロセス |
csrss.exe | クライアント/サーバー ランタイムサブシステム。「Windowsサブシステム」セッションプロセスを開始する |
dwm.exe | Aeroデスクトップウィンドウマネージャー |
explorer.exe | エクスプローラー |
lsass.exe | ローカルセキュリティオーソリティ。ローカルのユーザー認証を行う |
lsm.exe | ローカルセッションマネージャー。ローカルのターミナルセッションを管理する |
services.exe | サービスコントローラー。サービスを開始する |
smss.exe | Windowsセッションマネージャー。「Windowsサブシステム」や「POSIXサブシステム」などの各サブシステムを起動する。 |
svchost.exe | サービスホストプロセス。指定されたサービスを起動する |
System | Windows OSカーネルシステム |
System Idle Process | アイドルプロセス。他のプロセスが動作していないときに実行される(仮想的な)プロセス。システムの稼働率を測定する |
taskhost.exe | Windowsタスクのホストプロセス |
TrustedInstaller.exe | Windowsインストーラープロセス |
wininit.exe | Windows OSの初期化プロセス |
winlogon.exe | Windowsログオンアプリケーション。ユーザーのログオン/ログオフを管理する |
Windows OSの代表的なプロセス |
実際にシステム上で動作しているプロセスの例を次に示す。これはSysinternalsのProcess Explorerというツールでプロセスの一覧を表示したところだ。上の方にはOSカーネルを構成する重要なプロセスが表示されている。これを見ると例えば、サービスを構成するservice.exe(およびその子プロセスのsvchost.exe)はwininit.exeから起動されていることが分かる。
Process Explorerによるプロセスの一覧
SysinternalsのProcess Explorerというツールを使うと、タスクマネージャーよりも詳しくプロセスの状態を確認できる。プロセスの親子関係も確認できる。
(1)アイドルプロセス。これは仮想的なプロセスであり、他のプロセスが何も動作していないときに、このプロセスが動作しているものと見なされる。
(2)システムカーネルに相当するプロセス。(1)と(2)は通常のプロセスではないものの、見掛け上は他のプロセスと同じようにカーネル内部のプロセス一覧テーブルに格納され、その情報を取得できるようになっている。
(3)Windowsシステムの初期化やサービスの開始、ユーザーの実行環境の準備などを行う。
(4)いわゆるWindows OSカーネルとして動作しているプロセス群。
(5)ユーザーのログオンやログオフ、ユーザーセッションなどを管理する。
(6)ユーザー環境で動作するプロセス。最初にエクスプローラーが動作している。
今回はWindows OSのカーネルを理解するための第一歩として、プロセスとスレッド、スケジューリングなどについて見てきた。次回はメモリ管理について取り上げる。
Copyright© Digital Advantage Corp. All Rights Reserved.