linux内核之链表操作解析

        本文只是对linux内核中的链表进行分析。内核版本是linux-2.6.32.63。文件在:linux内核/linux-2.6.32.63/include/linux/list.h。本文对list.h文件进行简要分析,有必要的地方还会以图进行说明。

        代码分析:

链表结构体:

// 有前驱和后继,说明是双链表
struct list_head {
struct list_head *next, *prev;
};

链表头节点相关操作:

// 为head初始化,把head的next和prev都赋值为head的地址
// 因为定义的是宏,所以可以直接把后面的语句替换前面的宏直接看,
// struct list_head name = {&(name),&(name)};,这样会更容易理解
#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)

// 上面是使用宏进行的head初始化(静态初始化,因为宏会在程序预编译时期进行宏名替换)
// 下面这个是在运行时,内嵌到调用函数中。(因为这个是内联函数,调用时直接用函数体内嵌到被调函数中)
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}

链表节点插入操作:

// 这是一个增加插入的公用函数函数实现的是:
// prev <<=>> new <<=>> next,new是要新增的节点,pre和next是相邻的节点
// A <<=>> B 表示A的后继指向B,B的前驱指向A, 后面调用时,根据这个关系就更好理解了。
// 也可以直接看后面的list_add()函数,把结构体带入函数中也会好理解些
// 在内核中有很多这种函数类型:前面带有两个_的(即:__记住是两杠),一般来说这种类型的
// 函数都是不能直接调用的,一定要先通过包装这个函数,然后才能调用。这是个原始函数
#ifndef CONFIG_DEBUG_LIST
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;
}
#else
extern void __list_add(struct list_head *new,
     struct list_head *prev,
     struct list_head *next);
#endif
 
// 从链表头部插入节点 
// 下面函数就是包装了函数:__list_add(),实现从头节点到头结点的next之间插入元素
// head <<=>> new <<=>> head->next
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}

// 从链表尾部插入节点
// 包装了函数:__list_add(),实现从头节点的prev和头结点之间插入元素
// head-prev <<=>> new <<=>> head
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}

链表节点删除操作:

// 这是个删除的通用函数,实现得: prev <<=>> next
// 这是让prev和next建立起链接来。可以联系list_del()函数来分析
// 和上面分析一样该函数前缀为__所以一般是用来被包装的原始函数
// 其实这个函数并没有删除这个节点,而是把这个节点从链表上卸下来而已
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}

// 这是个删除的函数,参数则是将要删除的节点。
// 调用_list_del() 函数来让entry节点从链表中卸下来,并且让它的前后节点建立连接,
// 然后entry前后指针设置为个特殊的值,设置了这个值后的元素被访问时会引起页故障。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值