オペレーティング システムのステレオタイプ

1. オペレーティング システムの概要

1.1 システムコール、ユーザーモード、カーネルモード

リソースにアクセスするプロセスの特性に応じて、システムで実行されているプロセスを 2 つのレベルに分けることができます。

  1. ユーザーモード(ユーザーモード):ユーザーモードで動作するプロセスは、ユーザープログラムのデータを直接読み取ることができます。
  2. システム モード (カーネル モード): システム モードで実行されているプロセスまたはプログラムは、コンピューターのほぼすべてのリソースに制限なくアクセスできることは簡単に理解できます。

私たちが実行するユーザー プログラムでは、システム レベルのリソースに関連するすべての操作 (ファイル管理、プロセス制御、メモリ管理など) は、システム コールを通じてオペレーティング システムにサービス要求を行う必要があり、オペレーティング システムはそれらを完了します。その代わりに。
これらのシステムコールは、その機能によって次のカテゴリに大別できます。

  • 端末管理。デバイスの要求または解放、およびデバイスの起動とその他の機能を完了します。
  • ファイル管理。ファイルの読み取り、書き込み、作成、削除などの完全な機能。
  • プロセス制御。プロセスの作成、キャンセル、ブロック、およびウェイクアップ機能を完了します。
  • 通信を処理します。プロセス間のメッセージ パッシングやシグナル パッシングなどの完全な機能。
  • メモリ管理。ジョブが占有するメモリ領域のサイズとアドレスの取得、メモリの割り当て、リカバリ、および取得などの完全な機能。

1.3 では、ユーザー モードからカーネル モードに切り替えるにはどうすればよいでしょうか? (これら 3 つのタイプのどれが十分かを知る必要があるだけで、実際には、通常はいくつかのシステム コールだけが要求されます)

システム コール
これは、ユーザー モード プロセスがカーネル モードへの切り替えを積極的に要求する方法です. ユーザー モード プロセスは、オペレーティング システムによって提供されるサービス プログラムを使用して、システム コールを通じて作業を完了するために適用されます. たとえば、fork( ) は、新しいプロセスを作成するシステムを実際に実行します。システム コール メカニズムのコアは、 Linuxの int 80h 割り込みなど、オペレーティング システムがユーザーのために特別に開いている割り込みを使用することによって実現されます。
異常
CPU がユーザー モードで実行中のプログラムを実行しているときに、何らかの未知の例外が発生し、現在実行中のプロセスが例外を処理するカーネル関連のプログラムに切り替えられ、カーネル モードに移行します。フォルト例外。
周辺機器割り込み
周辺機器は、ユーザが要求した動作を完了すると、対応する割り込み信号を CPU に送信します.このとき、CPU は次に実行する命令の実行を中断し、処理プログラムの実行に戻ります.実行される命令はユーザモードのプログラムなので、当然ユーザモードからカーネルモードへの変換処理が発生します。たとえば、ハードディスクの読み取りと書き込み操作が完了すると、システムはハードディスクの読み取りと書き込みの割り込みハンドラーに切り替わり、後続の操作を実行します。

2. 工程管理

2.1 スレッド、プロセス、コルーチンの違い

スレッドとは、プロセスを分割した小さな操作単位で、プロセスの実行中に複数のスレッドを生成できます。スレッドとプロセスの最大の違いは、各プロセスが基本的に独立していることですが、同じプロセス内のスレッドは互いに影響を与える可能性が非常に高いため、各スレッドは必ずしも独立しているとは限りません。スレッド実行のオーバーヘッドは小さいですが、リソースの管理と保護には役立ちませんが、プロセスは正反対です。
コルーチンはユーザー モードの軽量スレッドであり、コルーチンのスケジューリングはユーザーによって完全に制御されます。スレッドは複数のコルーチンを持つことができ、コルーチンはオペレーティング システム カーネルによって管理されませんが、プログラムによって完全に制御されます。オペレーティング システムにスケジュールを任せるのではなく、自分でやったほうがよいでしょう. これが
コルーチンの概要です: コルーチンの主な機能は、シングル スレッドの条件下で同時実行の効果を達成することですが、実際にはまだシリアル (yield のように) スレッドは複数のコルーチンを使用すると、コルーチンはオペレーティング システム カーネルによって管理されず、プログラムによって完全に制御されます。

2.2 PCB とは? (同じ投稿の両側で PCB について質問されました)

データを含む同時実行に参加する各プログラムを独立して実行するには、プロセス制御ブロック (PCB、プロセス制御ブロック) と呼ばれる特別なデータ構造をオペレーティング システムで構成する必要があります。プロセスと PCB は 1 対 1 で対応し、ユーザー プロセスは変更できません。

2.3 プロセスとスレッドの作成とキャンセル中に何が起こったのですか? (多くの質問はありません。1 回だけ質問されました)

プロセス作成

  1. 割り当てスペース: オペレーティング システムは、プロセスがコード、データ、および実行ステータスを格納するためのメモリ スペースを割り当てます。
  2. ローダー: プロセスのプログラム コードとデータをディスクからメモリにロードして、プロセスの実行を開始できるようにします。
  3. プロセス制御ブロック (PCB) の初期化: オペレーティング システムはプロセスのプロセス制御ブロック (PCB) を作成します。これは、プロセス ID、プロセスの優先度、プロセスの状態など、プロセスのさまざまな状態と情報を記録するために使用されます。 .
  4. プロセス優先度の設定: オペレーティング システムは、システム内のプロセスの実行順序を決定するために、プロセスのタイプと要件に従ってプロセスの優先度を設定します。
  5. プロセスをレディ キューに追加する: オペレーティング システムはプロセスをレディ キューに追加し、システム スケジューラのスケジューリングの下で​​、プロセスに CPU リソースを割り当てて実行を開始できるようにします。

プロセスのキャンセル

  1. プロセスを終了する: プロセスの実行が終了するか、何らかの理由で強制的に終了する必要がある場合、オペレーティング システムはプロセスの実行を終了します。
  2. リソースの解放: オペレーティング システムは、プロセスが占有していたリソース (メモリ、開いているファイル、ネットワーク接続など) を解放します。
  3. プロセス ステータスの更新: オペレーティング システムは、プロセスのステータスを更新します。たとえば、プロセスのステータスを「実行中」から「終了」に変更します。
  4. プロセス制御ブロックの再利用: オペレーティング システムは、プロセス制御ブロック (PCB) を再利用して、プロセスが占有していたメモリを解放します。

スレッドの作成

  1. スレッド制御ブロック (TCB) の初期化: オペレーティング システムはスレッドのスレッド制御ブロック (TCB) を作成します。これは、スレッド ID、スレッドの優先度、スレッドの状態など、スレッドの状態と情報を記録するために使用されます。 .
  2. スタック スペースの割り当て: 各スレッドには、スレッド実行のコンテキスト情報を格納するための独立したスタック スペースが必要です。
  3. スレッドの優先度を設定する: オペレーティング システムは、システム内のスレッドの実行順序を決定するために、スレッドの種類と要件に従ってスレッドの優先度を設定します。
  4. レディ キューにスレッドを追加する: オペレーティング システムは、スレッドをレディ キューに追加して、システム スケジューラのスケジューリングの下で​​、スレッドに CPU リソースを割り当てて実行を開始できるようにします。

スレッドのキャンセル

  1. スレッド実行の一時停止: オペレーティング システムはスレッドに一時停止シグナルを送信してスレッドの実行を一時停止し、スレッドは一時停止シグナルを受信した後に実行を停止します。
  2. リソースの解放: スレッドが占有しているリソース (スタック領域、レジスタの内容など) は、他のスレッドが使用できるように解放する必要があります。
  3. スレッド状態の更新: オペレーティング システムは、スレッドの状態を「実行中」または「準備完了」から「終了」に変更します。
  4. スレッド制御ブロックを再利用する: オペレーティング システムはスレッド制御ブロック (TCB) を再利用して、スレッドが占有しているメモリ領域を解放します。
  5. スレッドの終了コードを処理します。スレッドは終了時に終了コードを返すことができ、オペレーティング システムはこの終了コードを親スレッドまたはメイン スレッドに渡してさらに処理します。

2.4 プロセスの 5 つの状態

すべてのプロセスは、作成状態、準備完了状態、実行状態、ブロック状態、および終了状態の 5 つの状態に分けることができます。動作中は主に、準備完了、実行中、ブロックの 3 つの状態があります。

2.5 プロセス スケジューリング アルゴリズム (高頻度テスト ポイント)

  • 先着順 (FCFS) スケジューリング アルゴリズム: 最初にキューに入る準備完了キューからプロセスを選択してリソースを割り当て、すぐに実行させ、完了するか特定のイベントが発生してブロックされるまで実行します。 CPU の占有をあきらめます。
  • ショート ジョブ ファースト (SJF) スケジューリング アルゴリズム: 実行可能キューから推定実行時間が最も短いプロセスを選択してリソースを割り当て、すぐに実行させ、完了するかイベントが発生し、ブロックされてあきらめるまで実行します。 CPU を占有します。
  • タイム スライス ラウンド ロビン スケジューリング アルゴリズム: タイム スライス ラウンド ロビン スケジューリングは、RR (ラウンド ロビン) スケジューリングとも呼ばれる、最も古く、最も単純で、公平で、最も広く使用されているアルゴリズムです。各プロセスには、タイム スライスと呼ばれる期間が割り当てられます。これは、プロセスの実行が許可される時間です。
  • マルチレベルのフィードバック キュー スケジューリング アルゴリズム: 上記で紹介したいくつかのプロセス スケジューリング アルゴリズムには、特定の制限があります。たとえば、短いプロセス優先のスケジューリング アルゴリズムは、短いプロセスのみを処理し、長いプロセスを無視しますマルチレベルのフィードバック キュー スケジューリング アルゴリズムは、優先度の高いジョブが応答を得られるようにするだけでなく、短いジョブ (プロセス) を迅速に完了させることもできます。であるため、現在、より優れたプロセス スケジューリング アルゴリズムとして認識されており、UNIX オペレーティング システムで採用されています。
  • Priority Scheduling : 各プロセスには優先度が割り当てられ、優先度が最も高いプロセスが最初に実行されます。同じ優先度のプロセスは FCFS 方式で実行されます。優先順位付けは、メモリ要件、時間要件、またはその他のリソース要件に基づいて行うことができます。

https://www.cnblogs.com/xiaolincoding/p/13631224.html

2.6 プロセス同期の方法

  • Mutex (ミューテックス) : 相互排除オブジェクト機構が採用されており、ミューテックス オブジェクトを所有するスレッドのみがパブリック リソースにアクセスする権利を持ちます。ミューテックス オブジェクトは 1 つしかないため、複数のスレッドが同時に共通リソースにアクセスしないことが保証されます。たとえば、synchronized キーワードや Java のさまざまなロックはすべて、このようなメカニズムです。
  • Semaphore (Semaphore) : 複数のスレッドが同じリソースに同時にアクセスできるようにしますが、このリソースに同時にアクセスするスレッドの最大数を制御する必要があります。
  • イベント (イベント) : 待機/通知: 通知操作によってマルチスレッド同期を維持し、マルチスレッド優先度の比較操作も便利に実現できます。

2.7 プロセス間通信の方法 (重要!)

  • パイプ/匿名パイプ (パイプ) : 親子プロセス間または親族関係を持つ兄弟プロセス間の通信に使用されます。
  • Named Pipes (Named Pipes) : 匿名パイプには名前がないため、アフィニティのプロセス間通信にのみ使用できます。この欠点を克服するために、よく知られているパイプラインが提案されています。よく知られているパイプは、先入れ先出し (先入れ先出し) に厳密に従います。既知のパイプはディスク ファイルの形式で存在し、マシン上の任意の 2 つのプロセス間の通信を実現できます。
  • シグナル (Signal) : シグナルは、イベントが発生したことを受信プロセスに通知するために使用される、より複雑な通信方法です。
  • メッセージ キューイング (メッセージ キューイング) : メッセージ キューは、特定の形式のメッセージのリンク リストであり、メモリに格納され、メッセージ キュー識別子によって識別されます。パイプラインとメッセージ キューの通信データは、先入れ先出しの原則に基づいています。パイプ (名前のないパイプ: メモリ内にのみ存在するファイル、名前付きパイプ: 実際のディスク メディアまたはファイル システムに存在する) とは異なり、メッセージ キューはカーネルに格納され、カーネルが再起動したとき (つまり、オペレーティング システムが再起動したとき) またはメッセージキューを正式に削除すると、メッセージキューが実際に削除されます。メッセージ キューは、メッセージのランダム クエリを実現でき、メッセージを先入れ先出しの順序で読み取る必要はなく、メッセージの種類に応じて読み取ることができ、FIFO よりも多くの利点があります。メッセージ キューは、信号によって運ばれる少量の情報、パイプラインがフォーマットされていないバイト ストリームしか運べないこと、およびバッファー サイズが制限されていることの欠点を克服します。
  • セマフォ (Semaphores) : セマフォは、共有データへのマルチプロセス アクセス用のカウンターです. セマフォの目的は、プロセス間の同期です。このスタイルの通信は、主に同期に関連する問題を解決し、競合状態を回避するために使用されます。
  • 共有メモリ (Shared memory) : 複数のプロセスが同じメモリ空間にアクセスでき、異なるプロセスが他のプロセスの共有メモリ内のデータの更新を時間内に見ることができます。このアプローチは、ミューテックスやセマフォなど、ある種の同期操作に依存する必要があります。これは間違いなく、プロセス間通信の最も有用な形式です。
  • ソケット: この方法は、主にネットワークを介したクライアントとサーバー間の通信に使用されます。ソケットは、TCP/IP をサポートするネットワーク通信の基本的な操作単位です.異なるホスト間のプロセス間の双方向通信の終点と見なすことができます.簡単に言えば、通信の 2 つの当事者間の合意です.関連する機能を完了する通信プロセス。

2.8 Producer-Consumer モデル (疑似コードを記述できるようにするため)

画像.png
この問題について注意すべき点がいくつかあります。

  • バッファが空になると、消費者は消費できなくなります
  • バッファーがいっぱいになると、プロデューサーは生産できなくなります
  • 1 つのスレッドが生成または消費している場合、他のスレッドは生成または消費などの操作を実行できなくなります。つまり、スレッド間の同期を維持するためです。
  • 条件変数とミューテックスの順序に注意してください

最初の 2 つの理由により、スレッド間の同期を維持する必要があります。つまり、1 つのスレッドが消費 (または生成) した後、他のスレッドが CPU を奪い合い、消費 (または生成) する機会を得ることができます。このために、スレッド間の同期に条件変数を使用できます: 生産者スレッドは、製品操作を実行する前に、必要なセマフォを取得するまで待機する必要があります; 同様に、消費者スレッドの場合、消費する前に待機する必要がありますスレッドが共有領域 (バッファ) にアクセスしていない場合は、消費操作を実行し、ロックを解除して他の使用可能なブロックされたスレッドを起動します。
疑似コードの実装
バッファー サイズが 10 で、いくつかのプロデューサー スレッドとコンシューマー スレッドがあるとします。プロデューサとコンシューマは互いに同等です. バッファプールがいっぱいでない限り, プロデューサはメッセージをバッファプールに送信できます. バッファプールが空でない限り, コンシューマはバッファプールからメッセージを取得できます. .


アイテムはバッファですでに使用されているリソースの数を表し、スペースはバッファ内で使用可能な
リソースの数を表します。
リソース

var items = 0, space = 10, mutex = 1;
var in = 0, out = 0;
item buf[10] = { NULL };

producer {
    while( true ) {
        wait( space );  // 等待缓冲区有空闲位置, 在使用PV操作时,条件变量需要在互斥锁之前
        wait( mutex );  // 保证在product时不会有其他线程访问缓冲区

        // product
        buf.push( item, in );  // 将新资源放到buf[in]位置 
        in = ( in + 1 ) % 10;
        
        signal( mutex );  // 唤醒的顺序可以不同
        signal( items );  // 通知consumer缓冲区有资源可以取走
    }
}

consumer {
    while( true ) {
        wait( items );  // 等待缓冲区有资源可以使用
        wait( mutex );  // 保证在consume时不会有其他线程访问缓冲区

        // consume
        buf.pop( out );  // 将buf[out]位置的的资源取走
        out = ( out + 1 ) % 10;

        signal( mutex );  // 唤醒的顺序可以不同
        signal( space );  // 通知缓冲区有空闲位置
    }
}

スレッド内の 2 つの待機の順序を逆にすることはできません。そうしないと、デッドロックが発生します。たとえば (スワップ後)、コンシューマーの 2 つの待機がスワップされます。プロデューサーがシグナル signal を送信した後、この時点でプロデューサー スレッドが再度実行する機会を得て、待機 (スペース) が実行されると、別のコンシューマー スレッドが実行されます。この時点でバッファが空の場合、wait(mutex) を実行すると、コンシューマは wait(items) でブロックされ、プロデューサも wait(mutex) でブロックされます。ロックの所有権が失われるため、両方のスレッドがブロックされ、デッドロックが発生します。

2.9 デッドロック

2.9.1 デッドロックが発生するために必要な 4 つの条件は?

  • 相互排除: リソースは非共有モードである必要があります。つまり、一度に 1 つのプロセスしか使用できません。別のプロセスがリソースを要求した場合、リソースが解放されるまで待機する必要があります。
  • Hold and wait : プロセスは少なくとも 1 つのリソースを保持し、別のプロセスによって保持されている別のリソースを待機する必要があります。
  • 非プリエンプティブ: リソースをプリエンプトできません。リソースは、リソースを保持しているプロセスがそのタスクを完了した後にのみ解放されます。
  • 循環待機: 待機中のプロセス {P0、P1、...、Pn} のグループがあり、P0 が待機しているリソースは P1 によって占有されており、P1 が待機しているリソースは P2 によって占有されています。 Pn-1 が待機しているリソースは Pn によって占有されており、Pn が待機しているリソースは P0 によって占有されています。

これらの 4 つの条件は、デッドロックが発生するための必要。つまり、システムにデッドロックがある限り、これらの条件は真でなければならず、上記の条件のいずれかが満たされない限り、デッドロックは発生しません。

2.9.2 デッドロックを回避する方法

アルゴリズムを通じて, 最も代表的なデッドロック回避アルゴリズムはダイクストラの銀行家のアルゴリズムです. 銀行家のアルゴリズムは一言で表されます. プロセスがリソースを申請するとき, 銀行家のアルゴリズムは最初のテストによってプロセスシステムは割り当て後に安全な状態になります. 安全でない場合, 仮の割り当ては無効になり, プロセスは待機を続けます. 安全な状態に入ることができれば, リソースはプロセスに割り当てられます.

2.9.3 デッドロックを解決する方法

デッドロックを解消する方法は、多角的に分析できますが、一般的には、予防、回避、検知、解放の4種類があります。

  • 予防とは、システムの実行中にデッドロックに必要な条件が常に満たされないように、並行プロセスのリソース要求を制限する戦略を採用することです。
  • 回避とは、システムがリソースを割り当てるときに、デッドロックの発生を回避するために、リソースの使用状況に応じて事前に予測を行うことを意味します。
  • 検出とは、システムが特別なメカニズムを持っていることを意味します. デッドロックが発生すると、メカニズムはデッドロックの発生を検出し、デッドロックに関連するプロセスとリソースを正確に判断できます.
  • 解除は検知に合わせた対策で、デッドロック状態からプロセスを解除するために使用します。

2.9.4 デッドロックの例

つまり、スレッド 1 がオブジェクト 1 のロックを保持し、スレッド 2 がオブジェクト 2 のロックを保持し、両方とも相手が保持しているオブジェクトのロックを解放するのを待ち、その後、それらが終了するまで待ちます。

public class DieLock {
 
    public static Object t1 = new Object();
    public static Object t2 = new Object();
 
    public static void main(String[] args){
        new Thread(){
            @Override
            public void run(){
                synchronized (t1){
                    System.out.println("Thread1 get t1");
 
                    try {
                        Thread.sleep(100);
                    }catch (Exception e){
 
                    }
 
                    synchronized (t2){
                        System.out.println("Thread2 get t2");
                    }
                }
            }
        }.start();
 
        new Thread(){
            @Override
            public void run(){
                synchronized (t2){
                    System.out.println("Thread2 get t2");
 
                    try {
                        Thread.sleep(100);
                    }catch (Exception e){
 
                    }
 
                    synchronized (t1){
                        System.out.println("Thread2 get t1");
                    }
                }
            }
        }.start();
    }
}

3. メモリ管理 (最も重要)

3.1 メモリ管理とは正確には何ですか?

オペレーティングシステムのメモリ管理は、主にメモリの割り当てと再利用を担当し(malloc関数:メモリの適用、free関数:メモリの解放)、アドレス変換、つまり論理アドレスを対応する物理アドレスに変換することも重要です。オペレーティング システムのメモリ管理機能です。

3.2 メモリ管理ページングの基礎知識 (非常にややこしい概念が多いため、一律にここに記載し、インタビューでは質問しません)

3.3 メモリ管理のいくつかのメカニズムについて話す

単純に連続割当管理方式非連続割当管理方式の2種類に分けられます。連続割り当て管理方式とは、ブロック同様に、非連続割り当て管理方式では、プログラムが使用するメモリを、ページ管理セグメント管理などの個別または隣接していないメモリに分散できます

  1. ブロック管理: 古代のコンピュータ オペレーティング システムのメモリ管理方法。メモリをいくつかの固定サイズのブロックに分割し、それぞれに 1 つのプロセスのみを含めます。プログラムの実行にメモリが必要な場合は、オペレーティング システムがメモリを割り当てますが、プログラムの実行に必要なメモリが小さい場合は、割り当てられたメモリの大部分がほとんど無駄になります。各ブロック内のこれらの未使用スペースはフラグメントと呼ばれます。
  2. ページング管理: メイン メモリをページごとに均等かつ一定の形式に分割します. ページは小さくなります. ブロック管理と比較して, 分割の粒度が小さくなり, メモリ使用率が向上し, 断片化が減少します. ページング管理は、ページテーブルを通じて論理アドレスと物理アドレスに対応します。
  3. セグメント管理: ページ管理はメモリ使用率を向上させますが、ページ管理のページには実際的な意味はありません。セグメント管理は、メイン メモリをセグメントに分割します. セグメントには実際的な意味があります. 各セグメントは論理情報のセットを定義します. たとえば, メイン プログラム セグメント MAIN, サブルーチン セグメント X, データ セグメント D およびスタック セグメント S などがあります. セグメント管理は、セグメントテーブルによって論理アドレスと物理アドレスに対応しています。

4.セグメント ページ管理メカニズム: セグメント ページ管理メカニズムは、セグメント管理とページ管理の利点を結合します。簡単に言えば、セグメントいくつかのページに分割することです。
簡単に言えば、ページは物理的な単位であり、セグメントは論理的な単位です。ページングは​​メモリ使用率を効果的に向上させ、セグメンテーションはユーザーのニーズをより適切に満たすことができます。

3.4 ページングとセグメンテーションの違いは何ですか?

共通点:

  • ページング メカニズムとセグメンテーション メカニズムはどちらも、メモリ使用率を改善し、メモリの断片化を減らすように設計されています。
  • ページとセグメントはどちらも個別に格納されるため、どちらもメモリを個別に割り当てる方法です。ただし、各ページおよびセグメント内のメモリは連続しています。

違い:

  • ページ サイズは固定されており、オペレーティング システムによって決定されます。セグメント サイズは固定されておらず、現在実行中のプログラムによって異なります。
  • ページングは​​オペレーティングシステムのメモリ管理のニーズを満たすためだけのものであり、セグメントは論理情報の単位であり、プログラム内のコードセグメントとデータセグメントとして具体化でき、ユーザーのニーズをよりよく満たすことができます。

3.5ページング管理の高速テーブルとマルチレベルページテーブルについて話します(なぜ答えるべきか、つまり高速テーブルが表示される理由、問題点を解決する方法に従って)

ページングは
​​オペレーティング システムのメモリ管理テクノロジであり、物理メモリを固定サイズのページ フレームに分割し、論理アドレス空間を同じサイズのページに分割します。ページング管理の中核は、ページ テーブルを介して論理アドレスと物理アドレスをマッピングすることです。
ページング管理では、ページテーブルに頻繁にアクセスする必要があるため、高速テーブルを使用するとページング効率が大幅に向上します。高速テーブルはページ テーブルの一種のキャッシュで、最近使用されたページ テーブル エントリを保存します。これらのページ テーブル エントリはアドレス変換に直接使用できるため、ホームページ テーブルへのアクセスのオーバーヘッドが回避されます。
マルチレベル ページ テーブルは、大きなページ テーブルを複数の小さなページ テーブルに分割するページ テーブル編成方法です. 各小さなページ テーブルはページ ディレクトリと呼ばれ、各ページ ディレクトリ エントリはページ テーブルを指します. のページ テーブル エントリは各ページ テーブルは、実際の物理ページ フレームを指します。これにより、ページ テーブルのサイズを効果的に削減できるため、メモリ領域を節約できます。さらに、マルチレベル ページ テーブルは、仮想アドレス空間の不連続な割り当てもサポートできるため、仮想アドレス空間を複数の領域に分割し、各領域で異なるページ テーブルを使用できます。
マルチレベル ページ テーブルと高速テーブルの組み合わせは、最新のオペレーティング システムで一般的なメモリ管理テクノロジであり、ページングの効率を大幅に向上させ、メモリ スペースを節約できます。特定の実装では、オペレーティング システムが異なれば、ページ テーブルのサイズやページ ディレクトリの数など、設計スキームやパラメータ設定も異なります。

3.5.1 高速テーブル (キャッシュレジスタです)

具体的な
原則 オペレーティング システムの高速テーブル (Translation Lookaside Buffer、TLB) は、仮想メモリから物理メモリ アドレスへの変換プロセスを高速化するために使用されるキャッシュ メカニズムです。
CPU がメモリにアクセスするとき、まず、対応するメモリ アドレスが TLB からキャッシュされているかどうかを確認しようとします。TLB にこのアドレスのマッピングがある場合、CPU は、アドレス変換のためにメモリ管理ユニット (MMU) にアクセスすることなく、このマッピングを直接使用できます。この方法は、毎回アドレス変換のために MMU にアクセスするよりもはるかに高速です。これは、TLB が通常、CPU の内部または非常に近くに配置されるように設計されており、キャッシュから直接アクセスできるためです。
CPU が必要なメモリ アドレス マッピングを TLB で見つけられない場合、MMU にリクエストを送信してアドレスの物理メモリ アドレスを取得し、マッピングを TLB に追加する必要があります。TLB のサイズが限られているため、TLB 内のすべてのエントリが使用され、使用可能なエントリがない場合、CPU は既存の TLB エントリを削除してスペースを空ける必要があります。
高速テーブルは、仮想メモリ システムをサポートするためによく使用されます。各プロセスは、連続したメモリ アドレス空間を独自に持っていると認識しますが、実際には物理メモリを共有します。TLB の役割は、仮想アドレスを物理アドレスに変換することです。これにより、複数のプロセスが同時に物理メモリを使用できるようになります。

3.5.2 マルチレベルのページテーブル

マルチレベル ページ テーブルは、仮想アドレス空間を複数レベルのページ テーブルに分割する仮想メモリの管理に使用されるデータ構造です。各ページ テーブルには一連のページ テーブル エントリが含まれ、各ページ テーブル エントリは仮想アドレスと物理アドレス間のマッピング関係を記録します。マルチレベルのページ テーブルを使用すると、オペレーティング システムはより大きな仮想アドレス空間をサポートし、ページ テーブルをより効率的に管理およびアクセスできます。
マルチレベル ページ テーブルは通常、1 つ以上のページ ディレクトリ テーブルとページ テーブルで構成されます。ページ ディレクトリ テーブルには一連のページ ディレクトリ エントリが含まれ、各ページ ディレクトリ エントリはページ テーブルを指します。ページ テーブルには一連のページ テーブル エントリが含まれ、各ページ テーブル エントリには仮想ページのマッピング情報が記録されます。プロセスが仮想アドレスにアクセスすると、オペレーティング システムは最初に仮想アドレスの上位ビットに従って対応するページ ディレクトリ エントリを見つけ、次にページ ディレクトリ エントリのポインタに従って対応するページ テーブルを見つけ、最後に対応するページを検索します。仮想アドレスの下位ビットに応じたページテーブル 物理アドレスを取得するためのページテーブルエントリ。
マルチレベル ページ テーブルの主な利点は、ページ テーブルのスペース要件を効果的に削減できることです。仮想アドレス空間は非常に大きいため、1 つのページ テーブルのサイズが非常に大きくなり、多数のページ テーブル エントリが必要になります。マルチレベル ページ テーブルを使用すると、オペレーティング システムは仮想アドレス空間を複数の部分に分割できます。各部分は小さなページ テーブルによって管理されるため、1 つのページ テーブルのサイズを大幅に縮小できます。同時に、各レベルのページ テーブルは必要な場合にのみアクセスする必要があるため、マルチレベル ページ テーブルはページ テーブルへのアクセス効率も向上させることができます。

3.6 仮想アドレスと物理アドレスについて話しますか? なぜ仮想アドレス空間があるのですか?

仮想アドレスと物理アドレスはどちらも、コンピュータ システムでメモリにアクセスするために使用されるアドレスです。
物理アドレスは、コンピューター メモリ内の実際の物理的な場所を指します。これは一意であり、メモリ内の物理的な場所を直接指しています。
仮想アドレスとは、CPU によって生成されるアドレスを指し、実際の物理的な場所を直接指すのではなく、オペレーティング システムとハードウェアの連携によってアドレス マッピングが完了し、仮想アドレスが物理アドレスにマッピングされます。仮想アドレス空間とは、オペレーティングシステムが各プロセスに割り当てた独立したアドレス空間で、各プロセスは他のプロセスとのメモリ競合を気にすることなく、メモリ空間全体を所有していると考えることができます。オペレーティングシステムは、仮想アドレスを通じてプロセスのメモリアクセスを管理し、メモリ保護やメモリ共有などの機能を実現します。
なぜ仮想アドレス空間があるのですか? 主に以下の理由があります。

  1. メモリ使用率の向上: 仮想アドレスはオペレーティング システムによってマップされるため、さまざまなプロセスが物理メモリを共有できるため、メモリ使用率が向上します。
  2. セキュリティの向上: オペレーティング システムは、仮想アドレスを介してプロセス間のメモリの分離と保護を実装できるため、悪意のあるプログラムが他のプログラムのメモリを破壊するのを防ぐことができます。
  3. プログラミングの簡素化: 仮想アドレスを使用すると、プログラマは、実際の物理アドレスがどのように割り当てられるかを気にすることなく、連続したアドレス空間を使用してメモリにアクセスできます。
  4. 便利なメモリ拡張: 物理メモリが不十分な場合、オペレーティング システムは、仮想アドレス空間の一部をハード ディスク上のスワップ ファイルにマップして、使用可能なメモリを拡張できます。

つまり、仮想アドレス空間の導入により、オペレーティング システムはメモリをより適切に管理し、メモリの使用率とセキュリティを向上させ、プログラムの設計を簡素化し、メモリの拡張を容易にすることができます。

3.7 仮想記憶の話? (プログラム局所性の原理)

これは、コンピューター、特に Windows システムを使用する場合に非常に一般的です。多くの場合、メモリを大量に消費するソフトウェアを使用していますが、これらのソフトウェアが占有するメモリは、コンピュータ自体の物理メモリをはるかに超えている可能性があります。なぜこれが可能なのですか?プログラムが仮想メモリを介してシステムの物理メモリのサイズを超える使用可能なメモリ空間を持つことができるのは、まさに仮想メモリ存在するためです。さらに、仮想メモリは各プロセスに一貫性のあるプライベート アドレス空間を提供します。これにより、各プロセスは専用のメイン メモリにあるように見えます (各プロセスには連続した完全なメモリ空間があります)これにより、メモリをより効率的に管理し、エラーを減らすことができます。仮想メモリは、コンピュータ システムのメモリ管理技術であり、コンピュータの仮想メモリを手動で設定できます。仮想メモリは単なる「ハードディスク領域を使用してメモリを拡張する」技術であると単純に考えないでください。仮想メモリの重要性は、連続した仮想アドレス空間を定義しメモリをハード ディスク空間に拡張することです。

3.8 仮想メモリの実装

仮想メモリの実現は、離散割り当てのメモリ管理方法に基づく必要があります。仮想メモリを実装するには、次の 3 つの方法があります。

  1. デマンドページングストレージ管理: ページング管理に基づいて、デマンドページングとページ置換機能が追加され、仮想メモリ機能がサポートされます。デマンド ページングは​​、現在、仮想メモリを実装するために最も一般的に使用されている方法です。デマンド ページング ストレージ管理システムでは、ジョブの実行が開始される前に、実行される一部のセグメントのみがロードされて実行されます。ジョブの実行中にアクセスするページがメモリ内にないことが判明した場合、プロセッサは、対応するページ置換アルゴリズムに従って対応するページをメイン メモリにロードするようオペレーティング システムに通知し、オペレーティング システムはまた、一時的に使用されていないページをメイン メモリに置き換えることもできます。
  2. 依頼区分保管管理: 区分保管管理を基に、依頼区分調整、区分入替機能を追加しました。要求分割ストレージ管理方法は、要求ページング ストレージ管理方法と同じです. ジョブが実行を開始する前に、実行するセグメントの一部のみをロードして実行します. ただし、プログラム セグメントはメモリにありません.メモリスペースがいっぱいで、新しいセグメントをロードする必要がある場合、特定のセグメントが置換関数に従って適切に呼び出され、新しいセグメント用のスペースが確保されます。
  3. セグメント ページング ストレージ管理の要求

ここでもっと教えて?多くの人は、リクエスト ページングとページング ストレージ管理を混同しがちですが、この 2 つの違いは何ですか?
要求ページング ストレージ管理は、ページング管理の上に構築されます。それらの根本的な違いは、プログラムが必要とするすべてのアドレス空間をメインメモリにロードするかどうかです。これが、ページングストレージ管理が仮想メモリを提供できる理由です。これについては、上記で分析しました。
それらの基本的な違いは、ジョブのアドレス空間全体が同時にメイン メモリにロードされるかどうかです。デマンド ページング メモリ管理では、ジョブのアドレス空間全体を同時にメイン メモリにロードする必要はありません。これに基づいて、要求ページング メモリ管理は仮想メモリを提供できますが、ページング メモリ管理は仮想メモリを提供できません。
上記の実装に関係なく、通常は次のものが必要です。

  1. 一定量の内部メモリと外部ストレージ: プログラムをロードするとき、プログラムの一部のみを内部メモリにロードする必要があり、残りの部分は外部ストレージに残してからプログラムを実行できます。
  2. ページフォルト割り込み実行する命令またはアクセスするデータがメモリ(ページまたはセグメントと呼ばれる)にない場合、プロセッサはオペレーティングシステムに対応するページまたはセグメントをメモリに転送するように通知し、続行しますプログラムを実行します。
  3. 仮想アドレス空間: 論理アドレスから物理アドレスへの変換。

3.9 ページ置換アルゴリズムについて話す

アドレス マッピング プロセス中に、アクセスするページがメモリ内にないことが判明した場合、ページ フォルト割り込みが発生します。
ページ フォールト割り込みは、アクセスするページがメイン メモリにないことを意味し、オペレーティング システムは、アクセスする前にページをメイン メモリに転送する必要があります。この時点で、メモリ マップト ファイルは実際にはページング ファイルになります。
ページ フォールト割り込みが発生したときに、現在のメモリに空きページがない場合、オペレーティング システムはメモリ内のページを選択し、それをメモリから移動して、ページを転送するためのスペースを確保する必要があります。どのページを削除するかを選択する規則をページ置換アルゴリズムと呼び、ページ置換アルゴリズムをページを削除するための規則と見なすことができます。

  • OPT ページ置換アルゴリズム (最適なページ置換アルゴリズム) : 最適な (最適、OPT) 置換アルゴリズムによって選択された除外されたページは、将来使用されないか、またはアクセスされなくなるページが最も長くなるため、最も低いページ フォールト率。しかし、現在、メモリ内の数千ページのプロセスのうち、将来最も長くアクセスされないページを予測することはできないため、このアルゴリズムは実現できません。通常、他の順列アルゴリズムの尺度として使用されます。
  • FIFO (First In First Out) ページ置換アルゴリズム (先入れ先出しページ置換アルゴリズム) : 常に最初にメモリに入るページを排除します。つまり、最も長くメモリに存在するページを選択します。排除されました。
  • LRU (Least Recent Used) ページ置換アルゴリズム (最も長い間使用されていないページ置換アルゴリズム) : LRU アルゴリズムは、各ページに、ページが最後にアクセスされてからの経過時間 T を記録するためのアクセス フィールドを与えます。ページを削除する必要がある ページを選択するときは、既存のページの中で T 値が最も大きいページ、つまり最も長い間使用されていないページを選択して削除します。
  • LFU(Least Frequency Used)ページ差し替えアルゴリズム(Least Frequency Used)ページ差し替えアルゴリズム(Least Frequency Used)ページ差し替えアルゴリズム:この差し替えアルゴリズムは、前の期間に最も使用されなかったページを除外ページとして選択する。

4.0 ソケット

ソケット TCP 3 回接続

スリーウェイ ハンドシェイク接続と組み合わせた TCP ソケット

画像.png
クライアントは connect() API を使用して、スリーウェイ ハンドシェイクをトリガーします。

ウェーブド TCP ソケットを 4 つ組み合わせる

補足質問

(1) プロセスの作成またはキャンセルのオーバーヘッドがスレッドのオーバーヘッドよりも大きいのはなぜですか?

  1. リソースの割り当て: 各プロセスには独自のアドレス空間、ファイル記述子、プロセス識別子、およびその他のリソースがあり、これらのリソースを割り当てて初期化する必要があり、スレッドはアドレス空間とプロセスのほとんどのリソースを共有するため、プロセスの作成にはより多くのリソースが必要です。スレッドを作成するよりも多くのリソース割り当て。
  2. コンテキスト切り替え: プロセスが切り替わるとき、プログラム カウンター、レジスタ、メモリ、I/O 状態などを含む、プロセスのすべてのリソース状態を保存および復元する必要があります。スレッドは、スレッド プライベート レジスタやスタック ポインターなどの少量のリソース状態を保存および復元するだけでよいため、プロセス コンテキストの切り替えのオーバーヘッドはスレッドのオーバーヘッドよりも大きくなります。
  3. プロセス間通信: プロセス間通信は、パイプ、メッセージ キュー、共有メモリなど、オペレーティング システムによって提供されるプロセス間通信メカニズムを介して実行する必要があり、これらのメカニズムはプロセス作成のコストを増加させます。また、システムのオーバーヘッドも増加します。
  4. セキュリティ: プロセスには独自のアドレス空間とリソースがあるため、プロセスはより分離され、システムのセキュリティをより適切に保護できます。ただし、このセキュリティにより、プロセスの作成と破棄のオーバーヘッドも増加します。

一般に、プロセスの作成または破棄はスレッドよりもコストがかかります。これは、プロセスがより多くのリソースを割り当て、より多くのコンテキスト スイッチを実行し、より多くのプロセス間通信メカニズムを使用し、より高いセキュリティを提供する必要があるためです。

(2) プロセス切り替えのコストがスレッドのコストよりも大きい理由

プロセスの切り替えは、プロセスの切り替え中にページ テーブルを切り取る必要があるため、スレッドの切り替えよりもコストがかかります。また、ページ テーブルの内容をスワップ インするには、プロセスのデータ セグメント コード セグメントをスワップ アウトする必要があるため、ページングが伴うことがよくあります。実行するプロセス。元のプロセスの内容は、スレッドのスーパーセットです。また、スレッドはスレッドのコンテキスト (関連するレジスタ ステータスとスタック情報) を保存するだけでよく、アクションは非常に小さいです。

(3) BufferCacheとPageCache

BufferCache と PageCache はどちらも、コンピューターのオペレーティング システムでデータをキャッシュするためのメカニズムですが、対象となるデータの種類とキャッシュの場所がわずかに異なります。
BufferCache は、主にファイル システムにデータ ブロックをキャッシュするために使用され、ファイル システム キャッシュの実装です。アプリケーションがファイル システム内のデータ ブロックにアクセスする必要がある場合、BufferCache はまずキャッシュ内にデータ ブロックのコピーが既に存在するかどうかを確認し、存在する場合はデータ ブロックを直接返し、存在しない場合は読み取ります。ディスクからデータをブロックして BufferCache にキャッシュし、後で高速にアクセスできるようにします。BufferCache は、ファイル システム カーネルにあるキャッシュ領域であり、ディスク I/O の数を減らし、ファイル システムのパフォーマンスを向上させることができます。
PageCache は、ページ データをメモリにキャッシュするために使用され、仮想メモリ システムの実装です。プロセスがページにアクセスする必要がある場合、PageCache は最初にキャッシュ内にページのコピーが既に存在するかどうかを確認し、存在する場合は直接ページを返し、存在しない場合はディスクとキャッシュからページを読み取ります。後で高速にアクセスできるように PageCache に保存します。PageCache はメモリ内にあるキャッシュ領域で、ディスク I/O の数を減らし、システム パフォーマンスを向上させることができます。
したがって、BufferCache と PageCache はどちらもデータをキャッシュするためのメカニズムですが、キャッシュ オブジェクトとキャッシュの場所がわずかに異なります. BufferCache はファイル システムにデータ ブロックをキャッシュするために使用され、PageCache はページ データをメモリにキャッシュするために使用されます.

(4) オーファンプロセスとゾンビプロセス

孤立プロセスとは、親プロセスが子プロセスより先に終了し、子プロセスが親プロセスを持たないプロセスになることを意味します。この状況は通常、親プロセスが異常終了したか、親プロセスが子プロセスの終了を適切に待機していないことが原因で発生します。孤立したプロセスは init プロセス (PID 1 のプロセス) に引き継がれ、init プロセスの子プロセスになるため、システムの通常の動作には影響しません。孤立したプロセスは、引き継がれるまでシステム リソースを占有する可能性があるため、システムの安定性とセキュリティのために、孤立したプロセスをタイムリーにクリーンアップすることが重要です。
ゾンビ プロセスとは、実行は完了したが、その親プロセスがその余波に対処していないプロセスを指します。子プロセス、結果として子プロセス プロセス記述子は解放されず、ゾンビ プロセスになります。ゾンビ プロセスはシステム リソースを占有しませんが、プロセス ID を占有します。ゾンビ プロセスが多すぎると、システムのプロセス ID リソースが使い果たされ、システムは新しいプロセスを作成できなくなります。ゾンビ プロセスが多すぎるのを避けるために、親プロセスは時間内に子プロセスのリソースを再利用する必要があります。
一般的にオーファンプロセスもゾンビプロセスも一種のプロセス状態ですが、その原因や現れ方は少し異なります。孤立プロセスは、親プロセスが子プロセスの前に終了することによって引き起こされ、init プロセスによって引き継がれます。ゾンビ プロセスは、親プロセスが子プロセスのリソースを時間内に再利用しないことによって引き起こされ、プロセスを占有します。 ID。

(5) CPU負荷

CPU負荷(CPU負荷)とは、実行中のプロセスやタスクがCPUリソースを占有する度合いを指し、通常は平均負荷(負荷平均)で表されます。平均負荷とは、CPU が一定時間内に実行しているプロセスまたはタスクの平均数、つまり、実行中のプロセスの平均長さを指します。
Unix/Linux システムでは、システムの稼働状況をサンプリングして計算することにより、平均負荷が得られます。一般に、平均負荷の値は実数であり、実行中のプロセス数と CPU リソースを待機しているプロセス数の合計を表します。たとえば、負荷平均が 1 のシステムは、実行中のプロセスの数が CPU コアの数と等しいことを意味し、負荷平均が 2 のシステムは、待機している CPU コアの数の 2 倍のプロセスがあることを意味します。 CPU リソース用。
CPU 負荷は、システム負荷を測定するための重要な指標です。高負荷は、システムが多くのタスクを実行しているか、CPU リソースが不足していることを示します。これにより、システムの応答が遅くなったり、フリーズしたりする可能性があります。したがって、管理者はリソースをスケジュールしたり、CPU 負荷に応じてシステム構成を最適化したりして、システムの安定性と効率を確保できます。

おすすめ

転載: blog.csdn.net/weixin_56640241/article/details/129867283