埋め込まれた面接筆記試験の質問 (14 日目)


序文

この記事では、疑問を解決する旅を続けます。

1. プロセス制御ブロック

ここではプロセスの PCB 制御ブロックのみを説明します。スレッドの TCP 制御ブロックの機能はプロセス PCB 制御ブロックの機能と同様です。

1.PCB制御ブロックの役割

プロセス制御ブロック (PCB) は、プロセス情報を管理および追跡するためにオペレーティング システムで使用されるデータ構造です。各プロセスには、オペレーティング システム内に対応する PCB があり、プロセスの実行と管理に関連するさまざまな情報が格納されます。PCB は、プロセスの作成、切り替え、終了などの操作において重要な役割を果たします。

PCB 通常包含以下信息:

1. プロセス識別子 (プロセス ID、PID): プロセスを一意に識別するために使用されます。

2. プロセス ステータス (プロセス ステータス): 実行中、準備完了、ブロック済みなど、プロセスの現在の実行ステータスを示します。

3. レジスタ内容 (Register Context): プログラム カウンタ (PC)、スタック ポインタ (SP) などを含むプロセスのレジスタ ステータスを保存します。プロセスが切り替わると、これらのレジスタの状態が PCB に保存され、切り替え時に復元できるようになります。

4. プロセスの優先度: プロセスの実行順序をスケジュールおよび決定するために使用されます。

5. プログラム カウンター (PC): 次に実行される命令のアドレスを記録します。

6. メモリ管理情報: プロセスのアドレス空間、ページテーブル、割り当てられた物理メモリなどを含みます。

7. ファイル記述子テーブル: プロセスによって開かれたファイルとネットワーク接続に関する情報を記録します。

8. リソース使用量: プロセスによって使用される CPU 時間、メモリ、ファイル記述子などのリソースの使用量をカウントします。

9. 親子関係とプロセス関係 (プロセス関係): 親プロセス、子プロセス、兄弟プロセス、およびプロセスのその他の関係を記録します。

10. 同期と通信: セマフォ、ミューテックス、パイプなどのプロセス間の同期と通信に使用されます。

PCB 是操作系统在进程创建时分配的数据结构,用于存储和管理进程的各种状态和信息。当操作系统进行进程切换时,它会保存当前进程的状态到其对应的 PCB 中,然后加载下一个进程的 PCB,从而实现进程之间的切换和调度。

PCB 在保证进程状态的正确性和执行的顺序上起着关键的作用,操作系统通过维护和管理 PCB 来实现进程的调度、资源分配和进程通信等功能,从而提供了一个稳定和可靠的多任务环境。

2. PCB の保管場所

PCB は、プロセスのユーザー空間ではなく、カーネルのメモリ空間に保存されます。これは、PCB のセキュリティと信頼性を確保し、プロセスによる不正なアクセスや改ざんを防ぐためです。

2. プロセスの 3 レベルのマッピング

オペレーティング システムでは、プロセスの 3 レベルのページ テーブル マッピングは、マルチレベルのページ テーブルを使用して大規模なメモリ マッピングを実現する仮想メモリ管理テクノロジです。これは、最新のオペレーティング システムで一般的なメモリ管理スキームの 1 つです。

従来の 2 レベルのページ テーブル構造は、仮想アドレスと物理アドレスの間のマッピング関係を管理する単一のページ テーブルで構成されます。ただし、システムの物理メモリが非常に大きい場合、この単一レベルのページ テーブルは大きなメモリ領域を占有し、マッピング関係を見つけるためにページ テーブルを走査するのに長い時間がかかります。これらの問題を解決するために、3 レベルのページ テーブルが導入されています。

3 レベルのページ テーブルの構造は 3 レベルのページ テーブルで構成され、各レベルにページ テーブルがあります。このうち、各ページテーブルはインデックスを通じて次のページテーブルのアドレスを決定し、レベルごとの検索のための高速なメモリマッピングを実現します。

具体来说,三级页表的结构如下:

1. トップレベルページテーブル (PML4、ページマップレベル 4): トップレベルページテーブルは、3 レベルのページテーブルの最上位レベルであり、仮想アドレスから物理アドレスへのマッピングが実行されます。最上位のページ テーブル構造には複数のページ テーブル エントリが含まれており、各ページ テーブル エントリは次のレベルのページ ディレクトリ テーブルを指します。

2. ページ ディレクトリ ポインタ テーブル (PDPT、ページ ディレクトリ ポインタ テーブル): ページ ディレクトリ テーブルは、3 レベルのページ テーブルの中間レベルであり、複数のページ ディレクトリ エントリを含みます。各ページ ディレクトリ エントリは、次のレベルのページ テーブルを指します。

3. ページ テーブル (PD、ページ ディレクトリ): ページ テーブルは 3 レベルのページ テーブルの最下位レベルであり、複数のページ テーブル エントリが含まれています。各ページ テーブル エントリは、最終的に物理ページにマップされます。

通过三级页表,系统可以将大型的虚拟地址空间分割成更小的块进行管理。只有在需要的情况下,才会加载或创建实际的页表项和物理页面,从而实现了懒加载和按需分配的内存管理机制。这样可以节省内存空间,并提高内存访问的效率。

总结起来,进程的三级映射是一种虚拟内存管理技术,通过三层级联的页表结构实现了大规模的内存映射。它提供了更灵活的内存管理和更高效的映射查找,适用于大型内存系统和需要管理大量虚拟地址空间的场景。

ここに画像の説明を挿入します

3、return、exit、pthread_exit

1.return: 呼び出し元に戻ります

2.exit: プロセスを終了します。

3.pthread_exit: スレッドを終了します

4. pthread_joinの機能

pthread_join() 関数を使用して、子スレッドの終了を待ち、スタック領域やその他のシステム リソースを解放します。

5. ミューテックスロックとセマフォの違い

スピン ロックとセマフォは、同期メカニズムで一般的に使用される 2 つの方法ですが、次のような違いがあります。

1. 動作方法: スピンロックはビジー待機の方法です。スレッドがスピン ロックを取得しようとしたときに、そのロックがすでに別のスレッドによって占有されている場合、スレッドはロックが使用可能になるまでロックのステータスをチェックし続けます。この方法は、ロック占有時間が非常に短い状況に適しています。セマフォはブロック メカニズムです。スレッドがセマフォを取得しようとするとき、セマフォのカウントが 0 の場合、スレッドはブロックされ、カウントが 0 でない場合にのみ実行を続行できます。

2. CPU 使用率: スピン ロックは、ロックの取得に失敗するとビジー待機を実行します。ロックを保持しているスレッドが長時間ロックを解放しない可能性があるため、待機中のスレッドがループでチェックを続け、CPU リソースを占有します。 。セマフォはブロック メカニズムを使用しており、待機中のスレッドは CPU リソースを占有せずに一時停止され、セマフォが使用可能になるまでウェイクアップされません。

3. 同期範囲: スピン ロックは主に重要なセクション、つまりコードまたは操作の小さなセクションを保護するために使用されます。スレッドは、クリティカル セクションに入る前にスピン ロックを取得し、クリティカル セクションを出た後にスピン ロックを解放します。セマフォを使用すると、リソース アクセスの数を制限し、複数のクリティカル セクションを保護できます。スレッドは、リソースが使用可能なときにセマフォを取得し、リソースの使用後にセマフォを解放します。

4. 適用可能なシナリオ: スピン ロックは、ロック占有時間が短く、ロック競合の可能性が低く、同時実行性の度合いが高い状況に適しています。スピンロックは、クリティカル セクションの実行時間が比較的短く、ビジー待機のオーバーヘッドが許容できる場合に効果的な選択肢です。セマフォは、ロックに時間がかかり、ロック競合の可能性が高く、同時実行性の度合いが低い状況に適しています。クリティカル セクションの実行時間が長い場合、またはリソースへの同時アクセスを制限する必要がある場合、待機をブロックすることで、ビジー待機によるリソースの浪費を効果的に回避できます。

6. リンクリストに循環があるかどうかを判断する方法

1. 2 つのポインタを作成し、1 つのポインタをファスト ポインタ (fast)、もう 1 つのポインタをスロー ポインタ (slow) と呼び、最初は両方ともリンク リストの先頭ノードを指します。

2. 高速ポインタは一度に 2 ノードずつ前方に移動し、低速ポインタは一度に 1 ノードずつ前方に移動します。

3. リンクされたリストにサイクルがある場合、高速ポインタと低速ポインタは最終的に一致します。

4. リンクリストにループがなければ、最終的には高速ポインタが先にリンクリストの末尾に到達することになり、この時点でリンクリストにループがないと判断できる。

#include <stdbool.h>

// 定义链表节点
struct ListNode {
    
    
    int val;
    struct ListNode* next;
};

bool hasCycle(struct ListNode* head) {
    
    
    if (head == NULL || head->next == NULL) {
    
    
        return false;  // 链表为空或只有一个节点,不可能有环
    }
    
    struct ListNode* slow = head;  // 慢指针
    struct ListNode* fast = head->next;  // 快指针
    
    while (fast != slow) {
    
    
        if (fast == NULL || fast->next == NULL) {
    
    
            return false;  // 快指针已经到达链表尾部,没有环
        }
        
        // 快指针每次移动两步,慢指针每次移动一步
        fast = fast->next->next;
        slow = slow->next;
    }
    
    return true;  // 快指针追上慢指针,存在环
}

要約する

こちらの記事で紹介しています。

おすすめ

転載: blog.csdn.net/m0_49476241/article/details/132135055