雙向循環鏈表詳細講解

雙向循環鏈表
[email protected], 2008-4-30
內核中很多地方使用雙向循環鏈表來維護一些信息,比如任務隊列。
雙向循環鏈表定義於include/linux/list.h,只有兩個成員next與prev分別指向後繼與前趨結點。一般內嵌到別的結構體內使用。避免了每個需要雙向循環鏈表的數據結構都自己維護指針並編寫鏈表操作函數。
struct list_head {
    struct list_head *next, *prev;      
};

一些常用的相關宏和函數如下:
INIT_LIST_HEAD(ptr)  初始化ptr節點爲表頭,將前趨與後繼都指向自己。
LIST_HEAD(name) 聲明並初始化雙向循環鏈表name。

static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
向鏈表中在prev與next之間插入元素new
static inline void list_add(struct list_head *new, struct list_head *head)
在鏈表中頭節點後插入元素new,調用__list_add()實現。
static inline void list_add_tail(struct list_head *new, struct list_head *head)
在鏈表末尾插入元素new,調用__list_add()實現。

static inline void __list_del(struct list_head * prev, struct list_head * next)
刪除鏈表中prev與next之間的元素。
static inline void list_del(struct list_head *entry)
刪除鏈表中的元素entry。

static inline void list_del_init(struct list_head *entry)
從鏈表中刪除元素entry,並將其初始化爲新的鏈表。
static inline void list_move(struct list_head *list, struct list_head *head)
從鏈表中刪除list元素,並將其加入head鏈表。
static inline void list_move_tail(struct list_head *list, struct list_head *head)
把list移動到鏈表末尾。

static inline int list_empty(const struct list_head *head)
測試鏈表是否爲空。

static inline void __list_splice(struct list_head *list, struct list_head *head)
將鏈表list與head合併。
static inline void list_splice(struct list_head *list, struct list_head *head)
在list不爲空的情況下,調用__list_splice()實現list與head的合併。
static inline void list_splice_init(struct list_head *list, struct list_head *head)
將兩鏈表合併,並將list初始化。

list_entry(ptr, type, member)

list_for_each(pos, head),__list_for_each(pos, head)
列出鏈表head中的每一項,前者有調用prefetch進行預取而後者沒有。。
list_for_each_prev(pos, head)
反向列出鏈表head中的每一項,有預取。

發佈了15 篇原創文章 · 獲贊 14 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章