list_for_each()的定義:
- /**
- * list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- */
- #define list_for_each(pos, head) \
- for (pos = (head)->next, prefetch(pos->next); pos != (head); \
- pos = pos->next, prefetch(pos->next))
list_for_each_safe()的定義:
- /**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos: the &struct list_head to use as a loop counter.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
- */
- #define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
由上面兩個對比來看,list_for_each_safe()函數(shù)比list_for_each()多了一個中間變量n
當(dāng)在遍歷的過程中需要刪除結(jié)點(diǎn)時,來看一下會出現(xiàn)什么情況:
list_for_each():list_del(pos)將pos的前后指針指向undefined state,導(dǎo)致kernel panic,另如果list_del_init(pos)將pos前后指針指向自身,導(dǎo)致死循環(huán)。
list_for_each_safe():首先將pos的后指針緩存到n,處理一個流程后再賦回pos,避免了這種情況發(fā)生。
因此之遍歷鏈表不刪除結(jié)點(diǎn)時,可以使用list_for_each(),而當(dāng)由刪除結(jié)點(diǎn)操作時,則要使用list_for_each_safe()。
其他帶safe的處理也是基于這個原因。