| オペレーティングシステム |
|---|
| 共通の特徴 |
プロセスとは実行中のプログラムであり、現代のあらゆるオペレーティングシステム(OS)に不可欠な要素です。OSは、プロセスにリソースを割り当て、プロセス間で情報を共有・交換できるようにし、各プロセスのリソースを他のプロセスから保護し、プロセス間の同期を可能にする必要があります。これらの要件を満たすために、OSは各プロセスのデータ構造を維持する必要があります。このデータ構造は、プロセスの状態とリソースの所有権を記述し、オペレーティングシステムが各プロセスを制御できるようにします。
マルチプログラミング
最近のオペレーティング システムでは、プログラムのインスタンスを複数同時にメモリにロードできます。たとえば、複数のユーザーが同じプログラムを実行する場合、各ユーザーはプログラムの別々のコピーをメモリにロードします。プログラムによっては、1 つのコピーをメモリにロードし、複数のユーザーがそのコピーを共有して、それぞれが同じプログラム コードを実行できるものもあります。このようなプログラムはリエントラントと呼ばれます。特定の瞬間にプロセッサは1 つのプログラムから 1 つの命令しか実行できませんが、各プロセスを一定期間プロセッサに一定間隔で割り当て、残りのプロセスを一時的に非アクティブにすることで、複数のプロセスを一定期間維持できます。複数のプロセスを同時にではなく、一定期間にわたって実行することを並行実行といいます。
マルチプログラミングまたはマルチタスクOSは、多数のプロセスを同時に実行できるオペレーティングシステムです。マルチプログラミングでは、プロセッサを各プロセスに一定期間割り当て、適切なタイミングで解放または再割り当てする必要があります。プロセスの実行中にプロセッサの割り当てを解除する場合は、そのプロセスを後で可能な限り効率的に再開できるようにする必要があります。
プログラムの実行中に OS がプロセッサの制御を取り戻し、割り当て解除または割り当てを実行するには、次の 2 つの方法があります。
- プロセスはシステム コール(ソフトウェア割り込みと呼ばれることもあります) を発行します。たとえば、ハード ディスク上のファイルへのアクセスを要求する I/O 要求が発生します。
- ハードウェア割り込みが発生します。たとえば、キーボードのキーが押されたり、タイマーが切れたりします (プリエンプティブ マルチタスクで使用)。
あるプロセスを停止し、別のプロセスを開始(または再起動)することをコンテキストスイッチまたはコンテキスト変更と呼びます。多くの最新のオペレーティングシステムでは、プロセスは多数のサブプロセスで構成できます。これにより、スレッドの概念が導入されます。スレッドはサブプロセス、つまり1つのプロセスのコード内で実行される独立した実行シーケンスと見なすことができます。スレッドは、分散システムやクライアントサーバーシステムの設計、そしてマルチプロセッサシステム上で実行されるソフトウェアにおいてますます重要になっています。
マルチプログラミングが効率を高める仕組み
ほとんどのコンピュータ プログラムに関連付けられたプロセスに見られる共通の特徴は、CPUサイクルとI/Oサイクルを交互に実行することです。CPU サイクルに必要な時間の部分では、プロセスが実行され、CPU を占有しています。I/O サイクルに必要な時間中は、プロセスはプロセッサを使用していません。その代わり、入出力の実行を待機しているか、実際に入出力を実行しています。この例としては、ディスク上のファイルの読み取りや書き込みがあります。マルチプログラミングの登場以前は、コンピュータはシングル ユーザー システムとして動作していました。このようなシステムのユーザーは、コンピューターが単一のユーザーに割り当てられている時間の大部分 (たとえば、ユーザーが情報を入力したりプログラムをデバッグしている時間) は、プロセッサがアイドル状態であることにすぐに気付きます。コンピューター科学者は、1 つのプロセスが入出力を待機している間は別のプロセスにプロセッサを使用させることで、マシンの全体的なパフォーマンスを向上できることを観察しました。ユニプログラミング システムでは、N人のユーザーがそれぞれt 1、t 2、 ...、t Nの実行時間でプログラムを実行する場合、 N人のユーザー全員のN個のプロセスを (連続して)サービスするのにかかる合計時間t uni は次のようになります。
- t uni = t 1 + t 2 + ... + t N。
しかし、各プロセスはCPUサイクルとI/Oサイクルの両方を消費するため、各プロセスが実際にCPUを使用する時間は、プロセス全体の実行時間のうちごくわずかな割合に過ぎません。したがって、プロセスiの場合、
- t i (プロセッサ) ≪ t i (実行)
どこ
t i (プロセッサ)はプロセスi がCPU を使用するのに要する時間であり、 t i (実行)はプロセスの合計実行時間です。つまり、プロセスが完了するまでに CPU サイクルと I/O サイクルが実行される時間です。
実際、通常、N個のプロセスで使用されるすべてのプロセッサ時間の合計が、いずれかのプロセスを実行する時間のごく一部を超えることはほとんどありません。
そのため、ユニプログラミングシステムでは、プロセッサは相当な時間アイドル状態になります。この非効率性を克服するために、Linux、UNIX、Microsoft Windowsなどの最新のオペレーティングシステムでは、マルチプログラミングが実装されています。これにより、プロセッサは、Xが実行のI/Oフェーズに関与しているときはいつでも、プロセスXから別のプロセスYに切り替えることができます。処理時間は単一ジョブの実行時間よりもはるかに短いため、マルチプログラミングシステムでN人のユーザー全員にサービスを提供する合計時間は、おおよそ次のように短縮されます。
- tマルチ= 最大 ( t 1 , t 2 , ..., t N )
プロセスの作成
オペレーティングシステムは、プロセスを生成するためのいくつかの方法を必要とします。単一のアプリケーションのみを実行するように設計された非常に単純なシステム(例えば、電子レンジのコントローラー)では、システム起動時に必要なすべてのプロセスが既に存在している可能性があります。しかし、汎用システムでは、動作中に必要に応じてプロセスを作成および終了する何らかの方法が必要です。 プロセスが生成される主なイベントは4つあります。
- システムの初期化。
- 実行中のプロセスによるプロセス作成システム コールの実行。
- 新しいプロセスを作成するためのユーザー要求。
- バッチ ジョブの開始。
オペレーティングシステムが起動すると、通常、システムの動作準備のためにいくつかの重要なプロセスが開始されます。これらのプロセスの中には、(人間の)ユーザーと対話し、ユーザーに代わって作業を行うフォアグラウンドプロセスがあります。その他のプロセスは、特定のユーザーに関連付けられておらず、特定の機能を持つバックグラウンドプロセスです。例えば、あるバックグラウンドプロセスは、受信メールを受け付けるように設計され、一日の大半はスリープ状態ですが、受信メールが届くと突然起動します。また、別のバックグラウンドプロセスは、マシン上でホストされているWebページへのリクエストを受け付けるように設計され、リクエストが届いた場合にのみ起動してサービスを実行します。
UNIXおよびLinuxにおけるプロセス生成は、 fork()またはclone()システムコールによって行われます。プロセス生成にはいくつかのステップがあります。最初のステップは、親プロセスがプロセスを生成するための十分な権限を持っているかどうかを検証することです。検証に成功すると、親プロセスはほぼ完全に複製され、固有のプロセスID、親プロセス、およびユーザー空間のみが変更されます。新しいプロセスはそれぞれ独自のユーザー空間を取得します。[ 1 ]
Windowsにおけるプロセスの作成は、CreateProcessA()システムコールによって行われます。新しいプロセスは呼び出し元プロセスのセキュリティコンテキストで実行されますが、それ以外は呼び出し元プロセスとは独立して実行されます。新しいプロセスが実行されるセキュリティコンテキストを変更するメソッドも存在します。新しいプロセスには、アクセスするための識別子が割り当てられます。呼び出し元スレッドを新しく作成されたプロセスと同期させるための関数も提供されています。[ 2 ] [ 3 ]
プロセスの終了
このセクションには独自の研究が含まれている可能性があります。このリストでは、プロセス終了の直接的な理由と、それに近い理由(「ユーザーのログオフ」など)を区別せずに組み合わせています。(2023年11月) |
プロセスが終了する理由は多数あります。
- バッチジョブが停止命令を発行する
- ユーザーがログオフ
- プロセスは終了するためのサービス要求を実行します
- エラーおよび障害状態
- 正常完了
- 時間制限を超えました
- メモリが利用できません
- 境界違反。例: 10 要素の配列の (存在しない) 11 番目の要素にアクセスしようとした
- 保護エラー。例: 読み取り専用ファイルに書き込もうとした
- 算術エラー。例:ゼロ除算を試みた
- 時間超過。例: プロセスがイベントに対して指定された最大値よりも長く待機した
- I/O障害
- 無効な命令。例: プロセスがデータ (テキスト) を実行しようとした場合
- 特権的な指導
- データの不正使用
- オペレーティングシステムの介入。例: デッドロックを解決する
- 親プロセスが終了すると子プロセスも終了する(カスケード終了)
- 保護者のリクエスト
2状態プロセス管理モデル
オペレーティングシステムの主な役割は、プロセスの実行を制御することです。これには、実行のインターリーブ パターンの決定とプロセスへのリソースの割り当てが含まれます。OS 設計の 1 つの部分は、各プロセスに期待する動作を記述することです。最も単純なモデルは、プロセスがプロセッサによって実行されているか、実行されていないかのいずれかであるという事実に基づいています。したがって、プロセスは、実行中または非実行中の 2 つの状態のいずれかにあると考えられます。オペレーティング システムが新しいプロセスを作成すると、そのプロセスは最初は非実行中 とラベル付けされ、システム内のキューに非実行中状態で配置されます。その後、プロセス (またはその一部) はメイン メモリに存在し、実行の機会を待つためにキュー内で待機します。しばらく時間が経つと、現在実行中 のプロセスは中断され、実行中状態から非実行中状態に移行して、プロセッサを別のプロセスに使用できるようになります。 OSのディスパッチ部は、NOT RUNNINGプロセスのキューから、プロセッサに転送する待機中のプロセスを1つ選択します。選択されたプロセスは、NOT RUNNING状態からRUNNING状態に再ラベル付けされ、新規プロセスの場合は実行が開始され、以前に中断されたプロセスの場合は再開されます。
このモデルから、OS のいくつかの設計要素を特定できます。
- 各プロセスを表現し、追跡する必要性
- プロセスの状態
- 実行されていないプロセスのキューイング
3状態プロセス管理モデル
2状態プロセス管理モデルはオペレーティングシステムの設計として完全に妥当ですが、BLOCKED状態が存在しないということは、アクティブなプロセスがCPUサイクルからI/Oサイクルに切り替わる際にプロセッサがアイドル状態になることを意味します。この設計ではプロセッサが効率的に使用されません。3状態プロセス管理モデルは、BLOCKED状態と呼ばれる新しい状態を導入することで、この問題を克服するように設計されています。この状態は、I/Oイベントの発生を待機しているプロセスを表します。この場合、I/Oイベントとは、デバイスの使用または他のプロセスからの信号を意味します。このモデルにおける3つの状態は次のとおりです。
- RUNNING:現在実行中のプロセス。
- READY:キューに入れられ、機会があれば実行できるように準備されているプロセス。
- ブロック: I/O 操作の完了など、何らかのイベントが発生するまで実行できないプロセス。
プロセスは、どの瞬間においても、3つの状態のうち1つだけになります。シングルプロセッサのコンピュータでは、RUNNING状態にあるプロセスは、どの瞬間においても1つだけです。READY状態とBLOCKED状態にあるプロセスは複数存在し、これらの状態にはそれぞれプロセス用のキューが関連付けられます。
システムに入るプロセスは、必ずREADY状態に移行しなければなりません。READY状態を経由してのみRUNNING状態に移行できます。プロセスは通常、RUNNING状態からシステムから退出します。3つの状態それぞれにおいて、プロセスはメインメモリの領域を占有します。ある状態から別の状態への遷移の理由は、ほとんどの場合明白ですが、そうでない場合もあります。
- 実行中 → 準備完了:この遷移の最も一般的な理由は、実行中のプロセスが中断なく実行できる最大許容時間に達したこと、つまりタイムアウトが発生したことです。その他の理由としては、低レベルスケジューラで使用されるスケジューリングポリシーや、より優先度の高いプロセスが準備完了状態になったことが挙げられます。
- 実行中 → ブロック:プロセスは、待機が必要な要求を行った場合、ブロック状態になります。OSへの要求は通常、システムコール(つまり、実行中のプロセスからOSコードの一部である関数への呼び出し)の形で行われます。例えば、プロセスがディスクからファイルを要求している場合や、メモリからディスク上のファイルにコードまたはデータの一部を保存している場合、プロセスはブロック状態になることがあります。
プロセスの説明と制御
システム内の各プロセスは、プロセス制御ブロック(PCB)、またはLinuxではプロセス記述子と呼ばれるデータ構造によって表されます。
プロセス識別: 各プロセスは、ユーザーの識別と、それをその記述子に接続するポインターによって一意に識別されます。
プロセス ステータス: プロセスの現在のステータス ( READY、RUNNING、BLOCKED、READY SUSPEND、BLOCKED SUSPEND)を示します。
プロセス状態: ジョブの現在の状態を示すために必要なすべての情報が含まれます。
アカウンティング:主に課金とパフォーマンス測定に使用される情報が含まれます。プロセスがどのようなリソースをどのくらいの期間使用したかを示します。
プロセッサモード
このセクションには独自の研究が含まれている可能性があります。用語に一貫性がないようです。文章は少なくとも部分的にx86を参照しているように見えますが、このアーキテクチャへの適用では一般的に使用されていない用語を使用しています。OSがソフトウェア割り込み時に保護モードを変更するという主張はおそらく誤りです。(2023年11月) |
現代のプロセッサには、プロセッサ内でのプログラムの実行能力を定義するモードビットが組み込まれています。このビットは、カーネルモードまたはユーザーモードに設定できます。カーネルモードは、スーパーバイザモード、モニターモード、またはリング0とも呼ばれます。
カーネルモードでは、プロセッサはハードウェアレパートリー内のすべての命令を実行できますが、ユーザーモードでは命令のサブセットしか実行できません。カーネルモードでのみ実行できる命令は、ユーザーモード命令と区別するために、カーネル命令、特権命令、または保護命令と呼ばれます。例えば、I/O命令は特権命令です。そのため、アプリケーションプログラムがユーザーモードで実行される場合、独自のI/Oを実行することはできません。代わりに、OSにI/Oの実行を依頼する必要があります。
カーネルシステムの概念
OSの重要な部分はカーネル モードで実行され、その他のソフトウェア(システム ユーティリティやアプリケーション プログラムなど)はユーザー モードで実行されます。これが OS と他のシステム ソフトウェアとの基本的な違いです。カーネル モードで実行されるシステムの部分はカーネル、つまり OS の核と呼ばれます。カーネルは信頼できるソフトウェアとして設計されており、ユーザー モードで実行される信頼できないソフトウェアによって密かに変更できない保護メカニズムを実装しています。OS の拡張機能はユーザー モードで動作するため、OS のコア機能は、正しく動作するためにこれらの拡張機能に依存しません。
OS機能の設計において重要な決定事項の一つは、カーネルに実装するかどうかです。カーネルに実装された場合、カーネルモードで動作し、カーネルの他の部分にアクセスし、それらから信頼されます。一方、ユーザーモードで実行された場合、カーネルデータ構造にアクセスすることはできませんが、呼び出しに必要な労力は最小限です。カーネルに実装された機能はシンプルですが、呼び出し時に必要なトラップメカニズムと認証プロセスは、比較的多くのリソースを消費する可能性があります。カーネルコード自体は効率的に実行されますが、呼び出しに伴うオーバーヘッドは大きくなる可能性があります。これは微妙ですが、重要な違いです。
システムサービスのリクエスト
ユーザー モードで実行されているプログラムがカーネルのサービスを要求できる手法は 2 つあります。
オペレーティング システムは、これら 2 つの機能のいずれか一方のみを使用するよう設計されていますが、両方を使用するようには設計されていません。まず、ユーザー プロセスが特定の対象システム関数を呼び出そうとしているとします。システム コールアプローチの場合、ユーザー プロセスはトラップ命令を使用します。この考え方は、システム コールがアプリケーション プログラムに対して通常のプロシージャ コールのように見えるようにすることです。OSは、実際の各システム コールに対応する名前を持つユーザー関数のライブラリを提供します。これらのスタブ関数のそれぞれには、OS 関数へのトラップが含まれています。アプリケーション プログラムがスタブを呼び出すと、トラップ命令が実行され、CPU がカーネル モードに切り替わり、呼び出される関数のエントリ ポイントに分岐します (OS テーブルを介して間接的に)。関数が完了すると、プロセッサがユーザー モードに切り替わり、制御がユーザー プロセスに戻されます。これにより、通常のプロシージャ リターンがシミュレートされます。
メッセージパッシング方式では、ユーザープロセスは要求されたサービスを記述したメッセージを作成します。次に、信頼できる送信関数を使用して、そのメッセージを信頼できるOSプロセスに渡します。送信関数はトラップと同じ目的を果たします。つまり、メッセージを慎重にチェックし、プロセッサをカーネルモードに切り替え、目的の機能を実装するプロセスにメッセージを配信します。一方、ユーザープロセスはメッセージ受信操作でサービス要求の結果を待機します。OSプロセスは操作を完了すると、ユーザープロセスにメッセージを返します。
これら2つのアプローチの違いは、OSの動作とアプリケーションプロセスの動作の独立性、そして結果として生じるパフォーマンスに関して重要な意味を持ちます。経験則として、システムコールインターフェースに基づくオペレーティングシステムは、異なるプロセス間でメッセージ交換を必要とするオペレーティングシステムよりも効率性を高めることができます。これは、システムコールをトラップ命令を用いて実装する必要がある場合でも当てはまります。つまり、トラップの実行コストは比較的高いものの、プロセス多重化、メッセージ形成、メッセージコピーに関連するコストが一般的に高いメッセージパッシングアプローチよりも効率的です。システムコールアプローチには、必ずしもOSプロセスが存在しないという興味深い特性があります。その代わりに、ユーザーモードで実行されているプロセスは、カーネルコードを実行しているときにカーネルモードに切り替わり、OSコールから戻るときにユーザーモードに戻ります。一方、OSが個別のプロセスの集合として設計されている場合、カーネルがユーザープロセスによってカーネルモードで実行される単なる関数の集合である場合よりも、特殊な状況でOSがマシンの制御権を取得するように設計するのが通常容易です。プロシージャ ベースのオペレーティング システムには、通常、ネットワークの スケジュールや処理など、マシンがアイドル状態になっている状況を処理するためのシステム プロセス( UNIXではデーモンと呼ばれる)が少なくともいくつか含まれています。
参照
参考文献
出典
- WindowsとUNIXを統合したオペレーティングシステム、コリン・リッチー。ISBN 0-8264-6416-5
- オペレーティングシステム、ウィリアム・スタリングス著、プレンティスホール、(第4版、2000年)
- マルチプログラミング、プロセス記述および制御
- オペレーティング システム - 現代的な視点、Gary Nutt、Addison Wesley、(第 2 版、2001 年)。
- プロセス管理モデル、スケジューリング、UNIX System V リリース 4:
- 現代のオペレーティングシステム、Andrew Tanenbaum、Prentice Hall、(第 2 版、2001 年)。
- オペレーティングシステムの概念、Silberschatz & Galvin & Gagne ( https://codex.cs.yale.edu/avi/os-book/OS9/slide-dir/ )、John Wiley & Sons、(第 6 版、2003 年)
