關於刪除元素的不安全性
為什麼說調用list_del()刪除元素有安全隱患?具體看源代碼:
static inline void __list_del(struct list_head * prev, struct
list_head * next)
{
next->prev = prev;
prev->next = next;
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
可以看出,當執行刪除操作的時候, 被刪除的節點的兩個指針被指向一個固定的位置(entry->next =
LIST_POISON1;
entry->prev = LIST_POISON2;)。而list_for_each(pos,
head)中的pos指針在遍歷過程中向後移動,即pos =
pos->next,如果執行了list_del()操作,pos將指向這個固定位置的next, prev,而此時的next,
prev沒有任何意義,別無選擇,出錯。
而list_for_each_safe(p, n, head) 宏解決了上面的問題:
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head);
\
pos = n, n = pos->next)
它采用了一個同pos同樣類型的指針n 來暫存將要被刪除的節點指針pos,從而使得刪除操作不影響pos指針!
實際上,list.h的設計可謂精益求精,煞費苦心,用簡潔的代碼突破計算機科學中傳統的鏈表實際機制,不僅考慮了單處理機,還利用了Paul
E.
McKenney提出的RCU(讀拷貝更新)的技術,從而提高了多處理機環境下的性能。關於RCU,請看http://www.rdrop.com/users/paulmck/rclock/