一.普通链表

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内核中的链表的实现,的确让人觉得是极为精巧的设计。不仅能大大减少代码量,还方便维护。

linux内核链表---挑战常规思维的更多相关文章

  1. linux内核链表分析

    一.常用的链表和内核链表的区别 1.1  常规链表结构        通常链表数据结构至少应包含两个域:数据域和指针域,数据域用于存储数据,指针域用于建立与下一个节点的联系.按照指针域的组织以及各个节 ...

  2. C语言 Linux内核链表(企业级链表)

    //Linux内核链表(企业级链表) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> ...

  3. 深入分析 Linux 内核链表--转

    引用地址:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 一. 链表数据结构简介 链表是一种常用的组织有序数据 ...

  4. Linux 内核链表

    一 . Linux内核链表 1 . 内核链表函数 1.INIT_LIST_HEAD:创建链表 2.list_add:在链表头插入节点 3.list_add_tail:在链表尾插入节点 4.list_d ...

  5. 深入分析 Linux 内核链表

    转载:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/   一. 链表数据结构简介 链表是一种常用的组织有序数据的数据结构,它通过指 ...

  6. Linux 内核 链表 的简单模拟(2)

    接上一篇Linux 内核 链表 的简单模拟(1) 第五章:Linux内核链表的遍历 /** * list_for_each - iterate over a list * @pos: the & ...

  7. Linux 内核 链表 的简单模拟(1)

    第零章:扯扯淡 出一个有意思的题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量,如 struct student { int a; //FIND(struct stu ...

  8. linux内核链表的移植与使用

    一.  Linux内核链表为双向循环链表,和数据结构中所学链表类似,具体不再细讲.由于在内核中所实现的函数十分经典,所以移植出来方便后期应用程序中的使用. /********************* ...

  9. [国嵌攻略][108][Linux内核链表]

    链表简介 链表是一种常见的数据结构,它通过指针将一系列数据节点连接成一条数据链.相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入 ...

随机推荐

  1. ExtJS与后台Java交互

    参考博客:http://blog.csdn.net/wanghuan203/article/details/8125970 开发环境:Eclipse + Tomcat + ExtJS6.0 工程目录结 ...

  2. Js中Array数组学习总结

    第一次写博客...有点方... 小白一枚(是真的小白),自学前端,下面来说说我在学习过程中总结的一些数组操作,如果说哪有错误,请各位大神多多指出,小的虚心接受. 引用类型分为Object类型(所谓的对 ...

  3. HDU5878(打表)

    I Count Two Three Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  4. HDU5832

    A water problem Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  5. ACM 刷题小技巧【转】

    转载自URl-team ACM做题过程中的一些小技巧. 1.一般用C语言节约空间,要用C++库函数或STL时才用C++; cout.cin和printf.scanf最好不要混用. 大数据输入输出时最好 ...

  6. GitHub客户端发布托管代码

    初试GitHub及客户端使用 突然想分享代码,于是记起来曾几何时有人提到过GitHub这个东西,于是便各种百度,注册申请了一个账号,下载了windows客户端,全英文网站就连新手教程也是全英的,现在想 ...

  7. 给Ubuntu 16.04更换更新源

    给自家的Ubuntu下载软件速度有点慢,毕竟是从国外下载软件,就想更换到国内比较好的更新源(就是这些软件所在的服务器),一般直接百度Ubuntu更新源就能出来一大堆,这时候最好是找和自己Ubuntu版 ...

  8. css3基础知识——回顾

    1.属性选择器 完全匹配的属性选择器 [id=article]{} 示例: <style> input[type=text]{ border: 2px solid red;} </s ...

  9. 基于ssh反向代理实现的远程协助

    本文描述了怎么通过ssh反向代理实现远程协助,并提供了相关代码. 可满足web开启远程协助功能后,维护人员能够通过ssh和http登录客户机器(包括在nat环境下) web开启该功能后,ssh才能登录 ...

  10. web开发的性能准则(减少页面加载时间方面)

    准则(概述) 减少 HTTP 请求 使用CDN加速 避免空的src或href属性值 增加过期头 启GZIP压缩 把css文件放到头部 把javascript放到尾部 避免使用css表达式 删除不使用的 ...