鏈表相關操做在內核源碼 include/linux/list.h 中linux
代碼大體分這幾部分:編程
1.數據結構聲明數據結構
struct list_head { struct list_head *next, *prev; };
是一個雙向循環鏈表,對於這種雙向循環鏈表,最好是抽象成head是豎着的一個圈,而不是一條線,這樣理解後邊的list_add(), list_add_tail() 時候會容易些。指針
2.初始化list頭部code
3.添加entry源碼
static __inline__ void __list_add(struct list_head * new, struct list_head * prev, struct list_head * next) { next->prev = new; new->next = next; new->prev = prev; prev->next = new; }
4.刪除entryclass
static __inline__ void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; }
添加、刪除操做是在__list_add() 、__list_del() 基礎上作的封裝,體現的是一種編程思想。基礎
1>從最基礎的開始寫,比較easy;循環
2>最基礎的,代碼可重複用,利用率高;遍歷
3>使代碼更有層次性。
5.判斷list_head是否爲空
6.鏈表對接
7.找到該元素所在的結構體
#define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
當前enetry在結構體中位置偏移爲
(unsigned long)(&((type *)0)->member)
當前指針所在位置爲
(ptr)
當前所在位置減去偏移就是該元素所在結構體的位置。
8.鏈表遍歷