linux kernel 中的链表(一)

linux kernel 中的链表

本文总结下最近学习的 kernel 中链表的使用和实现细节,本章主要是总结下链表部分提供的常用接口。

kernel 数据结构风格

linux kernel 在实现中,沉淀了不少的基础库,其中数据结构的封装和实现让人感觉非常的巧妙,而且用起来觉得非常的强大。
kernel 在实现一个通用的数据结构时,通常都是不带数据部分的,这点有些像C++了,他在给出一个数据结构时,只会给出结构本身的基础操作,对“业务”逻辑基本就是提供一个接口,让开发者自己搭积木。

链表的定义

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

链表的定义放在 linux/list.h 里面,定义很就是俩指针,由于他不带数据字段,需要开发者自己添加,比如就存个

typedef struct kv {
    int key, value;
} KV;
typedef struct mylist {
    struct list_head listnode;
    KV data;
} MYLIST;

链表的基础操作

kernel 中对于链表定义了很多基础操作,常用的主要有:

static inline void list_add(struct list_head *new, struct list_head *head); \\ 从链表头插入一个节点
static inline void list_add_tail(struct list_head *new, struct list_head *head); \\ 从链表尾插入一个节点

static inline void list_del(struct list_head *entry); \\ 删除某个节点

static inline void list_move(struct list_head *list, struct list_head *head); \\把一个节点移动到第一个
static inline void list_move_tail(struct list_head *list, struct list_head *head); \\ 把一个节点移动到最后一个位置

static inline void list_splice(struct list_head *list, struct list_head *head); \\合并两个链表(把 list 挂到 head 后面)

链表的常用宏

封装的内容分析下一章在描述,基本有这些就能完成一些普通的链表操作了。不过为了更顺畅的 coding,kernel 很人性化的做了很多基础使用宏。

/*
 * 初始化宏,作用是声明一个链表结构,并且让他的前驱和后继指针都指向自己
*/
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)、

/*
 * 初始化宏,作用是在使用过程中,再次初始化让他的前驱和后继指针都指向自己
*/
#define INIT_LIST_HEAD(ptr) do { \
                        (ptr)->next = (ptr); (ptr)->prev = (ptr); \
                        } while (0)

/*
 * 获取实例宏,kernel 里最经典的宏之一,几乎所有的数据结构都需要用上这个宏。
 * 宏的用法是给出某个结构指针,并且给出他被包含的结构体类型以及成员名称,返回该外包结构体的实例指针
*/
#define list_entry(ptr, type, member) container_of(ptr, type, member)

/*
 * 遍历宏
 * 第一个是用来遍历结构体本身
 * 由于每次遍历结构体本身大都涉及到取出其数据段,所以设计了第二条宏直接循环整个数据结构实例
*/
#define list_for_each(pos, head) \
                        for (pos = (head)->next, prefetch(pos->next); pos != (head); \
                        pos = pos->next, prefetch(pos->next))
#define list_for_each_entry(pos, head, member)      ……

以上基本就是链表结构提供出来的接口和方法,基于这些基本就可以自己动手玩一玩链表了,整体来说难度不大,写的很精练,也是理解很多 kernel 数据结构的基础。 linux/list.h 里面还放了一个 hlist ,是用来做 hash 链表的,下一章主要总结下 hlist 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值