Linux カーネル デバイス ドライバー カーネル リンク リストの使用上の注意

Linux カーネル デバイス ドライバー カーネル リンク リストの使用上の注意
/********************
 * カーネルにおけるリンクリストの応用************************/

(1)はじめに

Linux カーネルでは、デバイス リストやさまざまな機能モジュールのデータ構成など、データを整理するために多数のリンク リスト構造が使用されます。これらのリンク リストのほとんどは、include/linux/list.h に実装されている非常に優れたリンク リスト データ構造を使用します。

リンク リスト データ構造の定義は簡単です。

構造体list_head{
 構造体 list_head *次、*前;
};

list_head 構造体には、list_head 構造体を指す 2 つのポインター prev と next が含まれます。カーネルのデータ構造は通常、二重循環リンク リストに編成されます。

以前に紹介した二重リンクリスト構造モデルとは異なり、ここでの list_head にはデータ ドメインがありません。 Linux カーネルのリンク リストでは、リンク リスト構造にデータが含まれるのではなく、リンク リスト ノードがデータ構造に含まれます。のように:

構造体my_struct{
 構造体 list_head リスト;
 署名なしのロングドッグ;
 void *cat;
};

Linux のリンク リストには固定のヘッダーがなく、どの要素からでもアクセスを開始できます。リンク リストをトラバースするには、ノードから開始し、ポインターに従って次のノードにアクセスし、元のノードに戻るまで続けます。個々のノードはリンク リスト ヘッドと呼ぶことができます。

(2)リンクリストの初期化

a. 静的

コンパイル時にリンク リストを静的に作成し、それを直接参照する場合は、次のようになります。

構造体 my_struct mine={
 .lost = LIST_HEAD_INIT(mine.list);
 .犬 = 0,
 .cat = NULL
};
//またはstatic LIST_HEAD(fox);
/* struct list_head fox = LIST_HEAD_INIT(fox); に等しい */

b. ダイナミック

構造体 my_struct *p;
p = kmalloc(GFP_KERNEL、sizeof(my_struct));
p->犬 = 0;
p->cat = NULL;
INIT_LIST_HEAD(&p->リスト);

(3)業務一覧

カーネルは、リンク リストを操作するための一連の関数を提供します。

知らせ!これらの関数はすべて、1 つ以上の list_head 構造体ポインターをパラメーターとして受け取ります。 <linux/list.h> で定義されています

a. ノードを追加する

list_add(構造体list_head *new, 
     構造体list_head *head);
//指定されたリンクリストの先頭ノードの後に​​新しいノードを挿入します

b. リンクリストの末尾にノードを追加する

list_add_tail(構造体list_head *new, 
     構造体list_head *head);
//指定されたリンクリストの先頭ノードの前に新しいノードを挿入します

c. リンクリストからノードを削除する

list_del(構造体list_head *エントリ);
// リンクリストからエントリを削除する

d. あるリンクリストから別のリンクリストにノードを移動する

list_move(構造体list_head *リスト、 
     構造体list_head *head);

リンクリストからリスト項目を削除し、ヘッドの後に挿入する

e.list_empty(構造体list_head *head);

リンクリストが空の場合は0以外の値を返し、そうでない場合は0を返します。

f. リンクリストをマージする

list_splice(構造体list_head *リスト、 
      構造体list_head *head);
//知らせ!新しいリンクリストにはリストノードが含まれません

(4)リンクリストの走査

リンクリスト自体は重要ではなく、リンクリストを含む構造にアクセスすることが重要である。

a. リンクリストポインタからリンクリストを含む構造体へのポインタを取得する

list_entry(構造体list_head *ptr,
      構造体の型、 
      フィールド名);
  • ptr: list_head ポインタ
  • type_of_struct: ptrを含む構造体の型
  • field_name: 構造体内のリンクリストフィールドの名前

のように:

my_struct *p = (list_head *ptr、my_struct、リスト);

b. リンクリストを走査する

list_for_each(構造体list_head *カーソル、
       構造体 list_head *リスト);
//list_entry と組み合わせて使用​​されることが多い //注意! list_for_eachで走査する場合、ヘッドノードは含まれません

c. トラバース中に大きな構造へのポインタを取得する

list_for_each_entry(type *cursor, 
      構造体 list_head *リスト、
      メンバー);

d. リンクリストをトラバースしながら、トラバースした各ノードを解放する

list_for_each_entry_safe(型 *カーソル、 
     *tmp; と入力します。
     構造体 list_head *リスト、
     メンバー);

要約する

以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。これについてもっと知りたい場合は、次のリンクをご覧ください。

以下もご興味があるかもしれません:
  • Linux カーネル デバイス ドライバーのメモリ管理に関する注意事項
  • Linux カーネル デバイス ドライバー カーネル時間管理に関する注意事項
  • Linux カーネル デバイス ドライバー キャラクタ デバイス ドライバー ノート
  • Linux カーネル デバイス ドライバー仮想ファイル システムに関する注意事項
  • Linux カーネル デバイス ドライバー カーネル デバッグ テクニカル ノート集
  • Linux カーネル デバイス ドライバー proc ファイル システム ノート
  • Linuxカメラドライバの書き方の詳細説明
  • Linux におけるドライバモジュールのパラメータ転送プロセスの分析

<<:  Node.js環境でMySQLデータベースを素早く操作する方法を詳しく説明します

>>:  Alibaba Cloud Centos7.3 インストール mysql5.7.18 rpm インストール チュートリアル

推薦する

JavaScript ベースで年・月・日の 3 階層連携を実現

この記事では、年、月、日の3段階のリンクを実現するためのJavaScriptの具体的なコードを参考ま...

CocosCreator で http と WebSocket を使用する方法

目次1. HTTPGET 2. HTTP POSTウェブソケット4. Egretのhttpとwebs...

Windows 10 64 ビット版に MySQL 5.6.35 をインストールするためのグラフィック チュートリアル

1. MySQL Community Server 5.6.35をダウンロードするダウンロードアドレ...

CSSスプライト技術は複数の背景を1つのPNG画像に統合しますCSSポジショニング

アメリカのYAHOOがページ制作で使用している画像統合技術。これらのアイコン、列背景、画像ボタンを定...

HTML における要素の水平および垂直中央揃えに関する議論

ページをデザインするときには、ログイン ウィンドウを中央に配置するなど、DIV を中央に配置し、ペー...

mysql 変数の使用例の分析 [システム変数、ユーザー変数]

この記事では、例を使用して MySQL 変数の使用方法を説明します。ご参考までに、詳細は以下の通りで...

システム外のフォント参照とトランジション効果

コードをコピーコードは次のとおりです。 <span style="font-fami...

MySQL スローログ実践のまとめ

遅いログクエリ機能スロー ログ クエリの主な機能は、設定された時間しきい値を超える SQL ステート...

Vue で PC アドレスをモバイル アドレスにリダイレクトする方法

要件:PC側とモバイル側は2つの独立したプロジェクトです。2つのプロジェクトの内容は基本的に同じで、...

CSS でのナビゲーション バーとドロップダウン メニューの実装

1. CSSナビゲーションバー(1)ナビゲーションバーの機能ナビゲーション バーを使いこなすことは、...

初心者向け入門チュートリアル④:サブディレクトリのバインド方法

これが何を意味するのかを理解するには、まずサブディレクトリとは何かを知る必要があります。では、サブデ...

Reactのコンポーネント共同利用実装

目次ネスティング親子コンポーネント通信ブラザーコンポーネント通信撤回するReact の Linked...

特定のシンボルで複数の行と列に分割するMySQLの例

一部の障害コード テーブルでは、履歴またはパフォーマンス上の理由から、次の設計パターンが使用されます...

Dockerを使用してクローンリポジトリを使用してGitイメージを構築する

概要私は 1 年以上 Docker を使用しています。最近、サービスをすばやくオーケストレーションし...

JavaScriptイベント実行メカニズムの深い理解

目次序文ブラウザJS非同期実行の原理ブラウザのイベントループ実行スタックとタスクキューマクロタスクと...