• 内核链表与普通链表


    1、在Linux内核中经常能够看到 struct list_head 这样的一个结构体,这个就是内核中的一个链表,内核链表

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

    这个结构体中只有两个指向链表结构体的指针,分为前向指针和后向指针,因为可以用来构建一个双向链表,但是这个链表的用法与我们普通的链表的用法不一样,

    我们的一般的链表结构体中都会包含两部分:一个是指针(前向指针和后向指针)部分,还有就是有效数据部分。将我们链表需要存放的数据放在结构体中的有效数据

    区中,通过两个节点分别指向上一个节点和下一个节点。这是一般的链表的使用方法。

    (1)但是内核链表的结构体中只有两个指针,并没有有效数据区,所以内核链表的用法和我们的普通链表的用法是不一样的,我们使用内核链表的方法就是:

    自己建立一个结构体去包含这个内核链表,将整个结构体作为一个链表的节点,然后使用内置的链表的前向指针指向下一个结构体中内置的链表,使用内置的链表的

    后向指针指向上一个结构体中内置的链表。

    例如:

    struct A{                     

        struct list_head list;

        .........

    };

    struct A a;

    struct A b;

    struct A c;

    a.list.next = b.list;

    b.list.prev = a.list, b.list.next = c.list;

    c.list.prev = b.list;

    2、内核链表相关的函数和宏定义

    (1)内核链表的初始化

        #define LIST_HEAD_INIT(name) { &(name), &(name) }

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

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

    由上面可以知道,初始化就是将list_head中的两个指针都指向自己本身。初始化一个内核链表的方法:

    (1.1) 定义一个内核链表并进行初始化可以直接调用宏: LIST_HEAD(list);      展开之后:   struct list_head list = { &(list), &(list) }

    (1.2) 也可以定义和初始化分开, struct list_head list;    INIT_LIST_HEAD(&list);

      

    (2)内核链表的常用函数

    (2.1) list_add(struct list_head *new, struct list_head *head);         将节点插入到链表头部

            list_add_tail(struct list_head *new, struct list_head *head);   将节点插入到链表尾部

    (2.2) list_del(struct list_head *entry);    删除一个节点,并将他的指针清除0

            list_del_init(struct list_head *entry);   删除一个节点,并将他的指针再次指向自己本身

    (2.3) list_replace(struct list_head *old, struct list_head *new);   替换链表中的某个节点, old需要被替换的节点, new新的节点

            list_replace_init(struct list_head *old, struct list_head *new);   和上面的区别在于,把替换之后的老的节点进行初始化

    (2.4) int list_is_last(const struct list_head *list, const struct list_head *head);  测试一个节点是否为链表头节点,list是要测试的节点,head是一个链表头

            int list_empty(const struct list_head *head);   测试链表是否为空

    .............................................

     

  • 相关阅读:
    大数据HIve
    大数据笔记
    [Leetcode]653.Two Sum IV
    [Leetcode]652.Find Duplicate Subtrees
    [Leetcode]650.2 Keys Keyboard
    [Leetcode]648.Replace Words
    [Leetcode Weekly Contest]173
    [总结]最短路径算法
    [Leetcode]647.Palindromic Substrings
    [Leetcode]646.Maximum Length of Pair Chain
  • 原文地址:https://www.cnblogs.com/deng-tao/p/6044652.html
Copyright © 2020-2023  润新知