Linux下的链表使用简介

来源:互联网 发布:数组转字符串 编辑:程序博客网 时间:2024/05/29 07:28
数据结构在coding中起到了非常重要的作用,重要的数据结构包括了链表,栈,队列,树等等。这里介绍一些链表在内核中的实现。

我们书本上学到的链表的一般实现方式如下:

struct my_link{struct my_link *next; //next指向下一个节点DataType data;  //实际数据}

这种做法是数据嵌入到链表结构中。在内核中,存在着各种各样的数据,很多都需要链表操作。如果对每个数据结构都采用这样方式来实现链表操作的话,既容易出错,又无谓的增加了内核的大小。最好内核能提供一个统一链表操作接口,Liunx自然做到了。
数据结构:

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

使用:采用数据嵌入liat_head的方式来实现链表。举个例子

struct net_device{.........struct list_head dev_list;    .........};

那么怎么获得根据链表获得数据结构呢?
需要使用list_entry,最终调用container_of宏。
功能函数:
声明链表
LIST_HEAD_INIT()
LIST_HEAD
运行时初始化函数
INIT_LIST_HEAD

链表遍历及数据操作
list_for_each 遍历链表
list_for_each_entry 遍历链表并取得数据,相当于list_for_each 和list_entry 的结合
链表操作函数
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_replcace(struct list_head *old,struct list_head *new);
list_move(struct list_head *list, struct list_head *head);//从一个链表移动到另外一个
list_is_last(struct list_head *list, struct list_head *head);
list_empty(const struct list_head *head)
list_splice(const struct list_head *list,struct list_head *head);//合并链表
list_move_tail(struct list_head *list,struct list_head *head);//从尾部一个链表移动到另外一个

list扩展
  1,对应HASH列表,linux采用了单指针双循环链表。hlist表头只有一个指向首节点的指针,没有指向尾节点的指针,这样可能对于海量HASH表中表头能减少一半的空间消耗。
  2,对list的操作同样提供了以_rcu结尾的宏。RCU(Read-Copy Update)通过延迟写来提高性能。