这些链表结构体只能在内核使用,但其实我们在平时写链表时,可以仿照这样,精简。
如果我们需要某种数据结构的队列,就在这种结构内部放上list_head结构即可。例如:
typedef struct page {
struct list_head list;
.....
struct list_head lru;
....
}page_t;
这里面放了了2个list_head结构体(list和lru),这代表page结构体可以存在两个队列中,如下面图所示:

在这链表里面最关键的地方在
#define list_entry(ptr, type, member) /
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
通过它才可以访问链表里面真正的元素
例如:
list_head pstList;
struct page *page;
page = list_entry(pstList, struct page, list); 其中pstList 指向一个page结构体。
list_entry的原理的,通过这个结构体链表头在结构体中的偏移来获取 某个结构体的地址。
(unsigned long)(&((type *)0)->member)),这个是获取结构链表头的偏移值,如在page中,list偏移page的值
然后再把该地址减去该偏移才真正得到我们想要的结构体地址。