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 调用在循环里了.
posted on 2013-07-11 14:33 eric.geoffrey 阅读(171) 评论(0) 编辑 收藏 举报