Linux内核中的链表——struct list_head

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固定下来了。

container_of宏的定义:


                
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`struct crypto_queue` 是一个用于表示密码算法请求队列的数据结构。它包含了以下成员: ```c struct crypto_queue { struct list_head list; // 队列的链表struct list_head *backlog; // 指向积压请求的指针 unsigned int qlen; // 队列当前的请求数量 unsigned int max_qlen; // 队列的最大容量 }; ``` 下面对每个成员进行简要说明: - `list`:`struct list_head` 类型的成员,用于表示队列的链表头。`list_head` 是内核双向链表数据结构,它包含了指向前一个节点和后一个节点的指针。 - `backlog`:指向积压请求的指针。积压请求是指在队列等待处理的请求,即尚未被取出处理的请求。如果队列没有积压请求,则该指针将指向 `&queue->list`。 - `qlen`:无符号整数类型的成员,表示队列当前的请求数量。 - `max_qlen`:无符号整数类型的成员,表示队列的最大容量。当队列的请求数量达到最大容量时,新的请求将无法加入队列。 密码算法请求队列使用 `struct crypto_queue` 结构体来管理和跟踪队列的请求。通过使用链表和指针,可以方便地添加、删除和处理队列的请求。同时,`max_qlen` 成员可以用来限制队列的大小,以确保队列不会无限增长。 请注意,以上只是对 `struct crypto_queue` 结构体成员的简要说明。具体的实现可能会有所不同,具体取决于代码的上下文和使用场景。 希望以上解释能够帮助您理解 `struct crypto_queue` 结构体的定义和成员的含义。如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值