Linuxカーネルの設計と実装-カーネルデータ構造

メインコンテンツ

  • リンクリスト
  • キュー
  • マッピング
  • バイナリツリー

1.リンクリスト

  • 単一リンクリスト、二重リンクリスト
  • 循環リンクリスト

Linuxカーネルでのリンクリストの使用は、一般的なデータ構造で定義されているリンクリストとは異なります。
従来のリンクリスト:

従来の二重リンクリスト.png

従来のリンクリストの最大の欠点は、各ノードのdata1、data2などが(数やタイプに関係なく)不確実であるため、ユニバーサルではないことです。
Linuxのリンクリストはこの問題を巧みに解決します。Linuxのリンクリストはユーザーデータをリンクリストノードに保存しませんが、リンクリストノードをユーザーデータに保存します。
Linuxのリンクリストノードには2つのポインタ(preとnext)しかありません。この場合、リンクリストノードはユーザーデータから独立しているため、リンクリストの共同操作に便利です。

Linuxカーネルのリンクリスト:

Linuxカーネルの二重リンクリスト.png

最大の問題は、リンクリストのノードを介してユーザーデータを取得する方法です。
答えはcontainer_of()マクロです

#define container_of(ptr, type, member) ({          \
    const typeof(((type *)0)->member)*__mptr = (ptr);    \
             (type *)((char *)__mptr - offsetof(type, member)); })
  • タイプは通常、構造体、つまり、ユーザーデータとリンクリストノードを含む構造体です。
  • ptrは、タイプのリンクリストノードへのポインタです。
  • memberは、タイプでリンクリストノードを定義するために使用される名前です。

といった:

struct student
{
    int id;
    char* name;
    struct list_head list;
};
  • typecorrectstruct学生
  • ptrは、メンバータイプへのポインタであるstuctリストへのポインタです。
  • メンバーはリストです

container_ofマクロを分析してみましょう。

// 步骤1:将数字0强制转型为type*,然后取得其中的member元素
((type *)0)->member  // 相当于((struct student *)0)->list

// 步骤2:定义一个临时变量__mptr,并将其也指向ptr所指向的链表节点
const typeof(((type *)0)->member)*__mptr = (ptr);

// 步骤3:计算member字段距离type中第一个字段的距离,也就是type地址和member地址之间的差
// offset(type, member)也是一个宏,定义如下:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

// 步骤4:将__mptr的地址 - type地址和member地址之间的差
// 其实也就是获取type的地址

ステップ1、2、および4は比較的理解しやすいです。次の図では、ステップ3を説明するための例としてsturctStudentを使用しています。

  1. まず、((TYPE *)0)はアドレス0をタイプTYPEのアドレスに変換することを意味することを知っておく必要があります
  2. TYPEのアドレスは0なので、((TYPE *)0)-> MEMBERは、次の図に示すように、MEMBERのアドレスとTYPEのアドレスの差です。

ステップ3.pngを理解する

2.キュー

FIFO、言うまでもない

  • 初期化中、キューのサイズは常に2のn乗に設定されます
  • キューを使用する前に、キュー構造のスピンロックを解放します

3.マッピング

Pythonの辞書と同様に、
ハッシュテーブルは一種のマッピングですが、自己平衡二分探索木もデータを格納できます。たとえば、C ++のマップは赤黒の木です。最悪の場合、次のことができます。
Linuxカーネルでのパフォーマンスが向上します。マッピングはidrと呼ばれ、目的はid識別子にあるUIDをポインタにマッピングすることです。

4.赤黒木

5.アルゴリズムの複雑さ

大きなo記号は上限を表します(最悪の場合)
大きなθ記号は最小上限を表します

記事の最後に、Linuxカーネルのビデオによる説明をいくつか紹介します。

1. Linuxカーネルとプロセススケジューラ、完全なフェアスケジューラCFSの実現 https //www.bilibili.com/video/BV1hf4y1B7Yg/

2. Linuxカーネル丨赤黒木|デザインパターンとアルゴリズム https //www.bilibili.com/video/BV1ig4y1v7So/

3. Linuxカーネルの学習ビデオがここにあるので、学習は簡単です: https //www.bilibili.com/video/BV1m54y127Mb/

添付されているのは、Linuxカーネルの学習概要です。

 

 

 

 

 

おすすめ

転載: blog.csdn.net/Linuxhus/article/details/111936014