struct list_head
を使用してリンクされたリストとしてデータを整理するには リスト ルートを宣言する必要があります リスト エントリを宣言します リンケージ用。ルート エントリと子エントリの両方が同じ型 (struct list_head
)。 children
struct task_struct
のエントリ エントリは root
です . sibling
struct task_struct
のエントリ list entry
です .違いを確認するには、コードを読む必要があります。ここで children
と sibling
使用されています。 list_for_each
の使い方 children
の場合 children
の意味 root
です . list_entry
の使い方 sibling
の場合 sibling
の意味 list entry
です .
Linux カーネル リストの詳細については、こちらをご覧ください。
質問 :ここで「兄弟」を渡し、最終的に異なるオフセットを持つ別のリストを渡す理由は何ですか?
答え:
リストがこのように作成された場合:
list_add(&subtask->sibling, ¤t->children);
より
list_for_each(list, ¤t->children)
リストポインタを sibling
に初期化します 、したがって、 subling
を使用する必要があります list_entry へのパラメーターとして。それが方法 Linux カーネルは設計された API をリストします。
しかし、リストが別の場所で作成された場合 (間違い) ) 方法:
list_add(&subtask->children, ¤t->sibling);
これをリストを反復する必要があるよりも (間違った ) 方法:
list_for_each(list, ¤t->sibling)
children
を使用する必要があります list_entry
のパラメータとして .
これが役に立てば幸いです。
以下は、将来誰かを助けるかもしれない絵の表現です.上のボックスは親を表し、下の 2 つのボックスはその子を表します
前の回答に追加した図を次に示します。同じプロセスが親と子の両方になる可能性があり (図の Parent1 のように)、これら 2 つの役割を区別する必要があります。
直感的に、children
の場合 Parent0 の children
を指します Parent1、次に Parent0.children.next->next
Parent1.children.next
と同じです (図の緑色の円)。 、Parent0 の次の子ではなく、Parent1 の子を指します。