关于linux内核的数据结构——list_head
来源:互联网 发布:南风知我意2书包网 编辑:程序博客网 时间:2024/06/05 06:24
前言
最近想看linux内核,发现看了两周,还没啥进展,恰恰有些基础的东西往往忘记,这里先记录下最简单的东西,以后多记录。不可好高骛远,这里记录一个最基础的数据结构。list_head
正文
我们在学习谭浩强的《c程序设计》时候知道一个链表结构
最简单的结构是
struct student {int num;float score;struct student * next;};
具体用法我就不详细介绍,这里循环效率比较快。当然这种结构会有一个比较大的问题,只一个单向的。只用稍微改变以下。
struct student {int num;float score;struct student *next , *prev;};
可会我们还是有一个问题,发现没有?在任何时候需要一种list的时候,都要重新创建一个这样的结构体。如果是面向对象的语言也许很容易解决,直接声明一个借口就好了。可是这是c语言。可是c语言那么强大难道解决不了,当然不了。我们可以强制计算地址。
这里我们引出我们本节的强大的内容:
struct list_head { struct list_head *next, *prev;};
额,是不是太过简单了,开始学生的结构体就可以改变了:
struct student { struct list_head list ; int num; float score;};
我们只要根据list的地址计算出student的地址(ps这里貌似他们两个相等),就可以直接间接实现了面向对象的所谓的上溯造型。这里我们还是看下linux内核提供的几个宏定义,很厉害
#define memlist_entry list_entry#define list_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))//调用直接可以这样student stu1= memlist_entry(mlist, struct student, list);
最终调用我们变成了这样
student stu1= ((student*)((char *)(ptr)-(unsigned long)(&((student*)0)->list)))
其实抛开前面强制转化。ptr是我们head_list的指针,而最重要的是我们如何获得我们head_list在student结构体中的位置呢。就有了这个变态的代码(unsigned long)(&((stdent *)0)->list)
,因为我们让在0号地址上创建一个student结构体。当然list指针就是所谓的偏移量。至于为什么要把ptr强制转化成char。我认为啥都可以。感觉int也可以。
(ps我写的代码是在linux2.4上的。路径是、include/linux/list.h.最新版本的的list_entry方法有点复杂,我暂时没研究,不过原理基本差不多。)
然后我们再说几个无聊的问题。
#define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \}static __inline__ void __list_add(struct list_head * new, struct list_head * prev, struct list_head * next){ next->prev = new; new->next = next; new->prev = prev; prev->next = new;}static __inline__ void __list_del(struct list_head * prev, struct list_head * next){ next->prev = prev; prev->next = next;}
这里不太复杂。仅仅是让大家记得这个几个函数。
后记
慢慢努力学习,这种c的小技巧太多了,要好好学习。有空再研究下红黑树。
- 关于linux内核的数据结构——list_head
- 关于内核数据结构struc list_head的用法。
- 内核数据结构list_head的使用
- linux内核list_head结构的介绍
- 深入理解linux内核list_head的实现
- 深入理解linux内核list_head的实现
- 深入理解linux内核list_head的实现
- 深入理解linux内核list_head的实现
- Linux内核的list_head民用改造
- Linux内核的list_head民用改造
- Linux 内核list_head 学习
- linux内核之list_head
- Linux 内核list_head 学习
- Linux内核list_head学习
- Linux 内核list_head container_of
- Linux内核list_head分析
- linux内核数据结构之双向循环链表struct list_head
- linux 内核分析之list_head
- Java垃圾回收机制(GC)详解
- 实现标准equals的流程
- libsvm3.2.1 - SVM多分类简单实现
- A prompt box with an arrow
- 二叉排序树
- 关于linux内核的数据结构——list_head
- vue各种示例展示
- Spring中的@ControllerAdvice注解的使用
- 子窗口放在父窗口上(备忘录-1)
- eclipse+keil组合配置方案教程,可替代sourceinsight+keil
- First day of my blog
- html5 表单(三) select/label/fieldset
- Java的输入输出流
- Maven数据源配置