zoukankan      html  css  js  c++  java
  • Linux中实用链表介绍

    1. 为使用链表机制, 你的驱动必须包含文件 <linux/list.h>. 其定义了list_head结构:

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

    为使用Linux链表, 需要重新定义一个数据结构,结构中声明一个list_head类型的成员. 它的声明可能看起来象这样:
    struct new_struct
    {
      struct list_head list; /* 这个成员的位置无关,即可在结构中任意位置 */
      int data; /* 数据成员 */
      /* ... 添加其他字段 */
    };

    2. 链表在使用前必须初始化:
    用宏INIT_LIST_HEAD来初始化
    struct list_head new_list;
    INIT_LIST_HEAD(&new_list);
    或者直接用LIST_HEAD(new_list);

    3. 函数/宏介绍:
    list_add(struct list_head *new, struct list_head *head);
    在链表头后添加一个新的节点。(可用来创建堆栈)

    list_add_tail(struct list_head *new, struct list_head *head);
    在链表头前添加一个新的节点。(可用来创建队列)

    list_del(struct list_head *entry);
    list_del_init(struct list_head *entry);
    将给定的节点从链表中删除. 如果入口项可能注册在另外的链表中, 你应当使用 list_del_init, 它重新初始化这个链表指针.

    list_move(struct list_head *entry, struct list_head *head);
    list_move_tail(struct list_head *entry, struct list_head *head);
    将给定的入口项从它当前的链表里去除并且增加到 head 的开始. 为安放入口项在新链表的末尾, 使用 list_move_tail 代替.

    list_empty(struct list_head *head);
    如果给定链表是空, 返回一个非零值.

    list_splice(struct list_head *list, struct list_head *head);
    将 list 紧接在 head 之后来连接 2 个链表.

    list_entry(struct list_head *ptr, type_of_struct, field_name);
    根据struct list_head指针获取其对应的节点。
    这里ptr是一个指向使用的struct list_head的指针, type_of_struct是包含ptr的结构的类型, field_name是结构中链表成员的名字.

    list_for_each(struct list_head *cursor, struct list_head *list)
    这个宏创建一个for循环, 执行一次, cursor指向链表中的每个连续的入口项. 小心改变链表在遍历它时.

    void new_add_entry(struct new_struct *new)
    {
      struct list_head *ptr;
      struct new_struct *entry;

      list_for_each(ptr, &new_list)
      {
        entry = list_entry(ptr, struct new_struct, list);
        list_add_tail(&new->list, ptr);
        return;
      }
      list_add_tail(&new->list, &new_struct)

    }

    4.其他几个宏:
    list_for_each_prev(struct list_head *cursor, struct list_head *list)
    这个版本后向遍历链表.

    list_for_each_safe(struct list_head *cursor, struct list_head *next, struct list_head *list)
    如果你的循环可能删除列表中的项, 使用这个版本. 它简单的存储列表 next 中下一个项, 在循环的开始, 因此如果 cursor 指向的入口项被删除, 它不会被搞乱.

    list_for_each_entry(type *cursor, struct list_head *list, member)
    list_for_each_entry_safe(type *cursor, type *next, struct list_head *list, member)
    这些宏定义减轻了对一个包含给定结构类型的列表的处理.
    这里, cursor是一个指向包含数据类型的指针, member是包含结构中 list_head 结构的名子.
    有了这些宏, 没有必要安放 list_entry 调用在循环里了.

  • 相关阅读:
    Oracle notes
    jQuery笔记
    sql developer 要求enter the full pathname for java.exe
    [Error] WCF: SOAP security negotiation
    Unity
    Windows Form 开发笔记
    WP开发 资料整理
    乔迁新居:http://longwarelive.spaces.live.com/
    2008年1月1日启用 longware@live.cn
    《程序员》杂志揭晓2007软件中国年度评选
  • 原文地址:https://www.cnblogs.com/eric-geoffrey/p/3183909.html
Copyright © 2011-2022 走看看