Chcete-li uspořádat data jako propojený seznam pomocí struct list_head
musíte deklarovat kořen seznamu a deklarujte položku seznamu pro propojení. Jak kořenové, tak podřízené položky jsou stejného typu (struct list_head
). children
záznam struct task_struct
záznam je root
. sibling
záznam struct task_struct
je list entry
. Abyste viděli rozdíly, musíte si přečíst kód, kde children
a sibling
Jsou používány. Použití list_for_each
pro children
znamená to, co children
je root
. Použití list_entry
pro sibling
znamená to, co sibling
je list entry
.
Více o seznamech linuxových jader si můžete přečíst zde.
Otázka :Jaký je důvod, proč zde předáváme "sourozence", který nakonec obsahuje jiný seznam s jiným offsetem?
Odpověď:
Pokud byl seznam vytvořen tímto způsobem:
list_add(&subtask->sibling, ¤t->children);
Než
list_for_each(list, ¤t->children)
Inicializuje ukazatele seznamu na sibling
, takže musíte použít subling
jako parametr k list_entry. Tak jak linuxové jádro uvádí navržené API.
Ale pokud byl seznam vytvořen v jiném (špatně ) způsobem:
list_add(&subtask->children, ¤t->sibling);
Potom musíte tento seznam opakovat (špatně ) způsobem:
list_for_each(list, ¤t->sibling)
A nyní musíte použít children
jako parametr pro list_entry
.
Doufám, že to pomůže.
Následuje obrázkové znázornění, které může někomu v budoucnu pomoci. Horní pole představuje rodiče a dvě spodní pole jsou jeho děti
Zde je obrázek doplňující předchozí odpovědi. Stejným procesem může být rodič i dítě (jako Rodič1 na obrázku) a musíme tyto dvě role rozlišovat.
Intuitivně, pokud children
z Parent0 by ukazovalo na children
z Parent1, poté Parent0.children.next->next
(zelený kroužek na obrázku), což je stejné jako Parent1.children.next
, by ukazoval na potomka Parent1 namísto dalšího potomka Parent0.