2.4内核中的链表结构核2.6并没有太大区别。二者不同之处在于2.6扩充了两种链表数据结构:链表的读拷贝更新(rcu)和HASH链表(hlist)。这两种扩展都基于最基本的list结构。
链表数据结构定义:
这里的list_head没有数据域。在Linux内核链表中,不是在链表结构中包含数据,而是在数据结构中包含链表节点。
Linux内核链表接口
(1)声明和初始化
实际上Linux只定义了链表节点,并没有专门定义链表头,那么一个链表结构是如何建立起来的呢?这里是使用LIST_HEAD()这个宏来构建的。
这样,当需要用LIST_HEAD(nf_sockopts)声明一个名为nf_sockopts的链表头时,它的next、prev指针都初始化为指向自己。这样就构建了一个空链表,因为Linux用头指针的next是否指向自己来判断链表是否为空。
除了用LIST_HEAD()宏在声明的时候初始化一个链表以外,Linux还提供了一个INIT_LIST_HEAD宏用于运行时初始化链表:
(2)插入
对链表的插入操作有两种:在表头插入和在表尾插入。Linux为此提供了两个接口:
因为Linux链表是循环表,且表头的next、prev分别指向链表中的第一个和最后一个节点,所以,list_add和list_add_tail的区别并不大,实际上,Linux分别用以下两个函数来实现接口。
(3)删除
从接口函数中可以看到,被删除下来的prev、next指针分别被设为LIST_POISON1和LIST_POISON2两个特殊值,这样设置是为了保证不在链表中的节点项不可访问,对LIST_POISON1和LIST_POISON2的访问都将引起页故障。与之相对应,list_del_init()函数将节点从链表中解下来之后,调用LIST_INIT_HEAD()将节点置为空链状态。
405

被折叠的 条评论
为什么被折叠?



