Untuk mengatur data sebagai linked list menggunakan struct list_head
Anda harus mendeklarasikan daftar root dan nyatakan entri daftar untuk keterkaitan. Entri root dan turunan keduanya adalah tipe yang sama (struct list_head
). children
masuknya struct task_struct
entri adalah root
. sibling
masuknya struct task_struct
adalah list entry
. Untuk melihat perbedaannya, Anda harus membaca kodenya, dimana children
dan sibling
digunakan. Penggunaan list_for_each
untuk children
maksudnya apa children
adalah root
. Penggunaan list_entry
untuk sibling
maksudnya apa sibling
adalah list entry
.
Anda dapat membaca lebih lanjut tentang daftar kernel linux di sini.
Pertanyaan :Apa alasan kita melewati "saudara" di sini yang akhirnya daftar berbeda dengan offset berbeda?
Jawaban:
Jika daftar dibuat dengan cara ini:
list_add(&subtask->sibling, ¤t->children);
Daripada
list_for_each(list, ¤t->children)
Akan menginisialisasi penunjuk daftar ke sibling
, jadi Anda harus menggunakan subling
sebagai parameter ke list_entry. Begitulah API daftar kernel linux dirancang.
Namun, Jika daftar dibuat di tempat lain (salah ) cara:
list_add(&subtask->children, ¤t->sibling);
Daripada Anda harus mengulangi daftar ini (salah ) cara:
list_for_each(list, ¤t->sibling)
Dan sekarang Anda harus menggunakan children
sebagai parameter untuk list_entry
.
Harapan, ini membantu.
Berikut ini adalah representasi bergambar yang mungkin bisa membantu seseorang di masa depan. Kotak paling atas mewakili orang tua, dan dua kotak paling bawah adalah anak-anaknya
Ini adalah gambar tambahan dari jawaban sebelumnya. Proses yang sama dapat berupa orangtua dan anak (seperti Parent1 pada gambar), dan kita perlu membedakan antara kedua peran ini.
Secara intuitif, jika children
dari Parent0 akan mengarah ke children
Parent1, lalu Parent0.children.next->next
(lingkaran hijau pada gambar), yang sama dengan Parent1.children.next
, akan menunjuk ke anak dari Parent1 dan bukan ke anak berikutnya dari Parent0.