[解決済み] list_for_each_entry と list_for_each_entry_safe について説明する。
質問
Linuxのlist_for_each_entryと...entry_safeループの動作を説明できる方いらっしゃいますか? それは次のようなものです。
list_for_each_entry(type *cursor, struct list_head *list, member)
list_for_each_entry_safe(type *cursor, type *next, struct list_head *list,member)
これらのパラメータはどのような役割を果たし、どのようにリストを走査するのに使われるのでしょうか。
ありがとうございました。
解決方法は?
EDIT: すみません、遅くなりました、誤字脱字が多いです。
純粋に楽しいんです! :) 違いは
list_for_each_entry
はリストを反復している間に何かを削除すると壊れてしまいますし
list_for_each_entry_safe
は、そうではありません(もちろん、いくつかの余分なCPU命令を犠牲にして)。
カーネルは2重リンクリストに落ち着きましたが(これはあなたが理解していると思いますが)、list.hには1重リンクリストの実装があります。
struct list_head {
struct list_head *next;
struct list_head *prev;
};
リストのquot;head"と各ノードには同じ構造体が使用されていることに注意してください。リストが空の場合、headの
next
と
prev
のメンバーは、単にhead自身を指しているに過ぎない。 したがって、リストの反復処理は、単にheadの
next
メンバと同じアドレスでない限り、そのメンバをノードと呼びます。
prev
(停止するとき)です。 そうでなければ、あなたの
for
のボディが呼び出され
container_of()
マクロで実際の構造体へのポインタを取得し、それを使って遊びます。 そして、3番目のフィールドである
for
に移動し、次の
next
.
EDIT: おっと、失礼しました。パラメータの説明を求められていたのですね。 まあ、私があなただったら、誰かの言葉を鵜呑みにするのではなく、直接調べますね。 そのような場合、私は カーネル API ドキュメント 少なくともリンクリストライブラリについては存在します。 私は、赤黒木ライブラリにもそれを追加するパッチセットを通そうとしているのですが、何かを通すのはかなり大変な作業です。
また、注目すべきは http://kernelnewbies.org/FAQ/LinkedLists
簡単な例を挙げます。
struct list_head my_actual_list;
struct my_struct {
struct list_head node;
/* some other members */
};
/* in a function body somewhere... */
struct list_head *i;
list_for_each(i, &my_actual_list) {
struct my_struct *obj = list_entry(i, struct my_struct, node);
// do something with obj
}
list_entry
の単なるエイリアスです。
container_of
EDIT #2
OK、ではコメントでの質問に対する答えですが、私の答えをそのまま拡大解釈します。C++のSTLコンテナやCの配列などと比べると、奇妙な点がいくつかあるので、この概念を理解するのが難しいのは事実ですが、イディオムに慣れれば、ごく自然に思えるようになります。将来的には、構造体や関数、マクロの定義を自分で調べて、理解してから質問することをお勧めします。
まず最初に、リストの各ノードは、型
struct list_head
とリスト
それ自身
は、型
struct list_head
. したがって、この場合、誰がコンテナで誰が含まれるかは、単に使い方によるが、典型的には、これらのメンバに与えられた名前で表現される。 イテレータの型は
struct list_head *
. 以下はその例で、通常の関数 & マクロ呼び出しは、それに相当するコードに置き換えておきます。
struct my_container {
struct list_head list;
int some_member;
/* etc. */
};
struct my_obj {
struct list_head node;
int some_member;
/* etc. */
};
void func() {
struct my_container container;
struct my_obj obj1, obj2;
struct list_head *i;
/* INIT_LIST_HEAD(&container.list); */
container.list.next = &container.list;
container.list.prev = &container.list;
/* list_add_tail(&obj1.node); */
container.list.prev = &obj1.node;
obj1.node.next = &container.list;
obj1.node.prev = &container.list;
container.list.next = &obj1.node;
/* list_add_tail(&obj2.node); */
container.list.prev = &obj2.node;
obj2.node.next = &container.list;
obj2.node.prev = &obj1.node;
obj1.node.next = &obj2.node;
/* list_for_each(i, &container.list) { */
for (i = container.list.next; i != &container.list; i = i->next) {
struct my_obj *obj = list_entry(i, struct my_obj, node);
/* do stuff */
}
}
関連
-
[解決済み] TypeError: リストのインデックスは整数でなければならず、floatではない
-
[解決済み] リストを均等な大きさのチャンクに分割するにはどうしたらいいですか?
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] 割り当て後にリストが予期せず変更されました。その理由と防止策を教えてください。
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] リストにおけるdel、remove、popの違いについて
-
[解決済み] リストとタプルの違いは何ですか?
-
[解決済み] リストのすべての要素が条件に一致するかどうかを確認するには?
-
[解決済み】リストの内容を取り出して、別のリストに追加する
-
[解決済み】IEnumerable vs List - What to Use? どのように動作するのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] TypeError: リストのインデックスは整数でなければならず、floatではない
-
[解決済み] list_for_each_entry と list_for_each_entry_safe について説明する。
-
[解決済み] リストに指定されたメンバが含まれているかどうかを判断するルールを定義する
-
[解決済み] Haskellでelemを使わずにリストから重複を削除する
-
error C2955: 'std::list' : クラステンプレートの使用にはテンプレート引数のリストが必要です。
-
リストコレクションに関するいくつかの一般的な操作
-
QuerySetを配列に変換する:Pythonのlist()関数を直接使用、list()はstr()やint()に類似しています。
-
[解決済み] Prologでリストを追加するにはどうしたらいいですか?
-
[解決済み】Scalaのリスト連結、::と++の比較
-
[解決済み】大きなリストの中のn番目の項目のリストを返すPythonicな方法