Linux内核中的链表——struct list_head

本文介绍了Linux内核中的链表list_head的使用,包括如何将链表嵌入到数据结构中,以及container_of和list_entry宏的作用。此外,文章详细讲解了链表的初始化、添加节点(list_add和list_add_tail)、删除节点(list_del)等操作,并阐述了它们在双向环形链表中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux内核中经典链表 list_head 常见使用方法解析_风亦路的博客-CSDN博客_init_list_head      做内核驱动开发经常会使用linux内核最经典的双向链表 list_head, 以及它的拓展接口(或者宏定义): list_add , list_add_tail, list_del , list_entry ,list_for_each , list_for_each_entry ......       每次看到这些接口,感觉都很像,并且陈老师的那本书《深入理解linux内核》(UL...https://blog.csdn.net/wanshilun/article/details/79747710

我们之前认为的链表和写的链表 是这样定义的:

这种方法就是将数据结构嵌入链表

struct list_node{
    char buf[128];
    int  num;
    struct list_node *prev;
    struct list_node *next;

}

我们这样定义一个链表的节点,这个节点包含了 char buf[128] 和 int num 这两个数据就是数据域

prev和next就是指针域

可见我们是把数据结构放在了链表里,这样子就有一个问题:我们定义的list_node 的复用率很低。因为如果在其他场景需要使用链表 但是每个节点需要添加一个char name 那我们就要重新编写一个

struct list_node ! 这种低效率的方法 内核肯定是不会使用的!

Linux内核中的链表

内核中的链表的使用是将链表嵌入到数据结构中的!

内核中的标准链表是环形双向链表:

双向环形链表就像一个圈一样,所以每一个节点都可以作为头结点、尾结点 

内核版本:4.1.15, 在目录include/linux/types.h中定义了list_head结构:

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

next指针指向下一个链表节点,prev指针指向前一个节点。

可以看到,很简单,Linux内核中不是将数据结构嵌入链表,而是将链表嵌入数据结构。

list_head本身其实并没有意义——它需要被嵌入到你自己的数据结构中才能生效!

举个例子:

struct data_struct{
    char buf[128];
    int  num;
    struct list_head node;
}

我们将链表嵌入数据结构,将链表的节点和数据分离开来,这样对于不同的数据域需求 我们都可以通过list_head作为链表的节点。


contianer_of ()宏

container of()函数简介_叨陪鲤的博客-CSDN博客_container_of函数      在linux 内核编程中,会经常见到一个宏函数container_of(ptr,type,member), 但是当你通过追踪源码时,像我们这样的一般人就会绝望了(这一堆都是什么呀? 函数还可以这样定义??? 怎么还有0呢???  哎,算了,还是放弃吧。。。)。 这就是内核大佬们厉害的地方,随便两行代码就让我们怀疑人生,凡是都需要一个过程,慢慢来吧。        其实,原理很简单:  ...https://blog.csdn.net/s2603898260/article/details/79371024

container_of宏的作用:

通过:

1.指向该结构体中的成员member的指针ptr

2.该结构体类型type

3.成员member

来获得该数据结构的起始地址

(上面说的成员member 就比如我数据结构体定义的是:struct  data{ struct list_head list } 那list就可以作为成员member传入 作为container_of的第三个参数)

使用宏container_of()我们可以很方便地从链表指针找到父结构中包含的任何变量。这时因为在C语言中,一个给定结构体中的变量偏移在编译时地址就被ABI固定下来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值