liyux-1(内核通用链表)

本文详细介绍了Linux内核中list_head类型的定义与使用方法,包括如何初始化链表、链表节点与用户自定义结构的关联方式及常用操作如插入、删除等,并简要提及了哈希链表(hlist)的基本结构。

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

1. list_head类型结构:<Linux/list.h>

struct list_head

{

    struct list_head *next,*prev;

};

2. list_head使用

(1)将一个数据结构本身串成链表

    struct example_struct

    {

        struct list_head list;

        int priority;

        ...

    };

    创建list_head结构

    I. struct list_head example_list;

       INIT_LIST_HEAD(&example_list);

       注:INIT_LIST_HEAD定义:

             #define INIT_LIST_HEAD(ptr) do { /
                                 (ptr)->next = (ptr); (ptr)->prev = (ptr); /
                           } while (0)

   II. LIST_HEAD(example_list);

      注:LIST_HEAD定义:

            #define LIST_HEAD(name) /

                            struct list_head name = LIST_HEAD_INIT(name)

            #define LIST_HEAD_INIT(name) {&(name),&(name)} //这是对list_head结构体的初始化

    链表与用户结构连接

    从examplelist链表中得到节点对应的example_struct结构指针,其中ptr就是examplelist链表中list_head结构对应的指针

    struct example_struct *node = list_entry(ptr,struct example_struct,list);

    返回一个指向结构example_struct的指针

    注: <list.h>

           #define list_entry(ptr,type,member) /

                  container_of(ptr,type,member)

          list_entry的功能是得到链表中节点的结构,它的参数含义为:

          。ptr是链表中的一个struct list_head结构元素指针

          。type是用户定义的结构类型,其中,包含struct list_head结构成员

          。member用户定义结构中的struct list_head结构成员的名字

          <include/Linux/kernel.h>

          #define container_of(ptr,type,member) ({

                  //将链表中的元素ptr转换成结构type中成员member的类型

                  const typeof( ( (type *)0 )->member) * __mptr = (ptr);/

                  //__mptr减去member成员偏移地址正好是type结构地址

                  (type *)( (char *)__mptr - offsetof(type,member) );} )

          <include/Linux/stddef.h>

          #define offsetof(TYPE,MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)

(2)将某些链表与一个数据结构联系起来。

     这个主要是因为list_head的特性,利用list_head可以将多个数据结构进行相连。

3. 有关list_head的几个操作

    list_add(struct list_head *new,struct list_head *head);

    list_add(struct list_head *new,struct list_head *head);

    分别是在head前后插入list_head节点

    list_del(struct list_head *entry);

    list_empty(struct list_head *head);//判定链表是否为空

    list_splice(struct list_head *list,struct list_head *head);

    list_splice_tail(struct list_head *list,struct list_head *head);

    分别是从head前面或者后面插入list来合并两个链表

4. hlist 哈希链表

    struct hlist_head{

           struct hlist_node * first;

    };

    struct hlist_node{

           struct hlist_node *next,**pprev;

    };

    其中pprev是指向前一个节点中的next指针。

    常用的宏:

    #define HLIST_HEAD_INIT {.first = NULL}

    #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL}

    #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)

    #define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pptr = NULL)

    通过这个函数理解hlist结构,在next前加入n节点

    static inline void hlist_add_before(struct hlist_node *n,struct hlist_node *next)
    {
         n->pprev = next->pprev;
         n->next = next;
         next->pprev = &n->next;
         *(n->pprev) = n;
     }

5. 哦,抄书好麻烦,呵呵!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值