我对linux内核链表实现中的部分函数的理解——第一节

linux内核链表是一个双向循环链表,其实现与具体硬件平台无关,理解了linux内核链表的实现机制,我们能够把其移植到引用层程序设计当中。

        

linux内核链表相关的一些函数声明在include/linux/list.h中。

首先是链表数据结构的定义

struct list_head {
          struct list_head *next, *prev;
 };

这个不需要做过多的解释,就是这么定义的,根据内核源代码的说法是,使用这种next/prev entries的方式比使用一般的 single-entry routines所产生的代码要好。

 

接着是链表的创建和初始化

从内存中开辟一个头结点然后调用初始化函数就能完成链表的创建

在内核中,链表的初始化函数如下

static inline void INIT_LIST_HEAD(struct list_head *list)
{
 list->next = list;
 list->prev = list;
}

这是一个内联函数,函数参数为 list_head类型的头结点。

通俗点讲内核链表的初始化过程就是把前驱指针和后继指针都指向了自己。

然后是链表添加结点函数,表头添加和表尾添加结点函数如下

static inline void list_add(struct list_head *new, struct list_head *head)
{
 __list_add(new, head, head->next);
}

static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
 __list_add(new, head->prev, head);
}

可以看到,其实现倒是调用__list_add函数,那么__list_add函数函数又是如何实现的呢?

从内核中我们可以看到

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;
}

这个函数搞清楚了,添加结点也就没有什么问题了。这个函数的第一个参数是list_head类型的新的结点,第二个参数是它前面的那个list_head类型的结点,第三个参数是它后面的一个list_head类型的结点,这么一说也许就清晰了

实际上这个函数可以理解为图上的画线的过程,它总共画了四条带箭头的线。

          

      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux内核链表实现方式与传统链表实现方式有所不同。传统链表实现方式是在数据结构嵌入链表指针,而Linux内核链表实现方式是将链表节点嵌入数据结构。具体实现方式定义在`<include/linux/list.h>`,使用了`struct list_head`结构体来表示双向链表,其包含了`next`和`prev`指针。 在Linux内核链表,删除指定节点的方式是使用`list_del`函数,该函数将指定节点的`next`和`prev`指针设置为`LIST_POISON1`和`LIST_POISON2`。为什么不将这些指针设置为NULL呢?这是因为`LIST_POISON1`和`LIST_POISON2`是非NULL的指针,在普通环境会引发page faults(页面错误),从而用于验证是否所有链表节点都已经被初始化。这样可以帮助检测和排查未初始化的链表节点。 在遍历链表时,可以使用`list_first_entry`宏来获取链表的第一个节点。这个宏会返回链表头节点的下一个节点,并使用`list_entry`宏将该节点转换为所需的数据结构类型。 综上所述,Linux内核链表实现方式独特,将链表节点嵌入数据结构,使用`list_del`函数删除节点时将指针置为`LIST_POISON1`和`LIST_POISON2`,并可通过`list_first_entry`宏遍历链表。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [linux 内核链表实现](https://blog.csdn.net/qq_35031421/article/details/103938221)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值