首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 开发>linux 内核>文章内容
深入分析 Linux操作系统的内核链表
来源:www.unix5.com 作者:riechelr_hl 发布时间:2007-05-26  
  

当我们需要删除 nf_sockopts 链表中添加的 new_sockopt 项时,我们这么操作:

 

list_del(&new_sockopt.list);
 

被剔除下来的 new_sockopt.list,prev、next 指针分别被设为 LIST_POSITION2 和 LIST_POSITION1 两个特殊值,这样设置是为了保证不在链表中的节点项不可访问--对 LIST_POSITION1 和 LIST_POSITION2 的访问都把引起页故障。与之相对应, list_del_init() 函数把节点从链表中解下来之后,调用 LIST_INIT_HEAD() 把节点置为空链状态。

c) 搬移

Linux 提供了把原本属于一个链表的节点移动到另一个链表的操作,并根据插入到新链表的位置分为两类:

 

 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);
  

例如 list_move(&new_sockopt.list,&nf_sockopts) 会把 new_sockopt 从它所在的链表上删除,并把其再链入 nf_sockopts 的表头。

d) 合并

除了针对节点的插入、删除操作,Linux 链表还提供了整个链表的插入功能:

 

static inline void list_splice
(struct list_head *list, struct list_head *head);
  

假设当前有两个链表,表头分别是 list1 和 list2(都是 struct list_head 变量),当调用 list_splice(&list1,&list2) 时,只要 list1 非空,list1 链表的内容把被挂接在 list2 链表上,位于 list2 和 list2.next(原 list2 表的第一个节点)之间。新 list2 链表把以原 list1 表的第一个节点为首节点,而尾节点不变。如图(虚箭头为next指针):

当 list1 被挂接到 list2 之后,作为原表头指针的 list1 的 next、prev 仍然指向原来的节点,为了避免引起混乱,Linux 提供了一个 list_splice_init() 函数:

 

static inline void list_splice_init
(struct list_head *list, struct list_head *head);
  
  

该函数在把 list 合并到 head 链表的基础上,调用 INIT_LIST_HEAD(list) 把 list 设置为空链。

3. 遍历

遍历是链表最经常的操作之一,为了方便核心应用遍历链表,Linux 链表把遍历操作抽象成几个宏。在介绍遍历宏之前,我们先看看怎么样从链表中访问到我们真正需要的数据项。

a) 由链表节点到数据项变量

我们知道,Linux 链表中仅保存了数据项结构中 list_head 成员变量的地址,那么我们怎么样通过这个 list_head 成员访问到作为它的所有者的节点数据呢?Linux 为此提供了一个 list_entry(ptr,type,member) 宏,其中ptr是指向该数据中 list_head 成员的指针,也就是存储在链表中的地址值,type 是数据项的类型,member 则是数据项类型定义中 list_head 成员的变量名,例如,我们要访问 nf_sockopts 链表中首个 nf_sockopt_ops 变量,则如此调用:

 

 list_entry(nf_sockopts->next, struct nf_sockopt_ops, list);

  

这里 "list" 正是 nf_sockopt_ops 结构中定义的用于链表操作的节点成员变量名。

以上只是一些略详介绍,当然,kernel,的面纱,还须读者们,更多,更深的去揭露,欢迎大家共同交流,

共4页: 上一页 [1] [2] 3 [4] 下一页
 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·使用 Linux 系统调用的内核命令
·Linux 2.6.11内核文件IO系统调用
·Linux操作系统的源代码目录树结
·Linux用户态与内核态的交互讲解
·Linux内核对I/O端口的管理实现(
·Linux内核可装载模块对设备驱动
·概述Linux系统的驱动框架及驱动
·详解Linux 2.6内核新文件系统变
·Linux系统可卸载内核模块完全指
·FreeBSD手册讲解(一)--配置FreeB
·编译Linux操作系统的内核讲解
·Linux系统可卸载内核模块完全指
  相关文章
·走向Linux系统高手之路 编译内核
·Linux内核入侵检测安全增强实现
·Linux内核可装载模块对设备驱动
·Linux内核入侵检测安全增强实现
·详细解析Linux操作系统的内核空
·Linux操作系统内核启动参数详细
·剖析Linux 2.6内核在嵌入式上的
·Linux操作系统的源代码目录树结
·使用 Linux 系统调用的内核命令
·Linux内核对I/O端口的管理实现(
·Linux内核对I/O端口的管理实现(
·内核设计篇

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!