内核链表

一.普通链表

1.一般教材上的链表定义如下:

struct node{ 
int content; node *next; };

它将指针域放在链表节点中,上一个节点指针域中的值指向下一个节点的首地址,以此将a1,到an这n个在内存地址中分布不连续的值连接起来,构成顺序表。

2.链表作为一种数据结构,自然需要为它实现一些函数,比如插入节点,搜索和删除节点等,用来维护它的数据集。

(1).创建链表  node *create(...){...}

(2).插入节点  node *insert(...){...}

(3).删除节点  node *delete(...){...}

...

 

3.如果在一个程序中需要使用两种类型的链表,如下所示

struct node1{             
     int data;               
     node1 *next;              
};
struct node2{
       int data;
       node2 *next;  
};

 

那么当我们在定义它们各自的操作的时候,就需要为每个链表各自定义一套方法。比如说创建链表的操作:

node1 *create(...){...};
node2 *create(...){...};

这样就大大增加了代码量,并且较多的指针操作容易带来隐患。

 

二. linux的内核链表

  链表在linux内核中是很常用的数据结构,在进程管理,内存管理等很多地方都有使用。比如著名的task_struct就是用链表组织的。在这样一个使用很多链表的系统中,为每个链表定义自己的一套方法是不现实的。因此使用了一种统一的组织形式。

1.内核链表定义

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

它是一个不含数据域的节点,用来将含有数据域的节点“串”起来。

 

2.一个例子如下

struct my_struct{
     int data;
     list_head *mylist;    
};

如果用它创建一个节点

 
  
struct my_struct first = {
     .data = 10,
   .mylist = LIST_HEAD_INIT(first.mylist) } ;

创建四个节点并对节点中的数据成员和链表节点成员进行初始化,如下图所示

  可以看到,这种组织形式将节点链域与数据域分离开来,节点中的mylist域的作用就是将各个分离的节点穿起来,而mylist使用统一的list_head类型,对链表进行操作时只需要修改节点中的mylist域,而与整个结构体的类型无关,这样就不需要为每一个链表都定义一套自己的操作函数。

 

为了更好地理解内核链表的优点,画为如下的形式,可以当数据域是附着在list_head类型的节点域上的,将数据域与指针域分离。当我要增加或删除节点时,只需要改动节点中的指针域即可,而这样的指针就像一根线,如果在系统中只有一种线,那么就只需要定义一套链表操作函数

 

三.总结

  书本上的知识一般只是讲述原理,技巧性的东西不会涉及太多。在实际应用中,可能一般的套路是行不通的。linux内核中的链表的实现,的确让人觉得是极为精巧的设计。不仅能大大减少代码量,还方便维护。

 

转载于:https://www.cnblogs.com/zclm/p/6559566.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值