Linux内核数据结构之链表
来源:互联网 发布:python 顶级黑客 编辑:程序博客网 时间:2024/05/22 10:28
链表
在学习《Linux内核设计与实现》中链表结构时,对<scripts\kconfig\list.h>(我看的内核是2.6的,在其他版本对链表的定义可能不在这个目录中)中的宏定义:container_of()很困惑,所以google一番,现记录自己对其的理解:
#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
宏定义的三个参数的含义分别为:
type:一般是个结构体,也就是包含用户数据和链表节点的结构体
ptr:是指向type中链表节点的指针
member:是type中定义链表节点时用的名字
比如:
struct student{ int id; char* name; struct list_head list;};
- type是struct student
- ptr是指向struct list_head的指针,也就是指向member类型的指针
- member就是list
对于container_of宏:
// 步骤1:将数字0强制转型为type*,然后取得其中的member元素((type *)0)->member // 相当于((struct student *)0)->list// 步骤2:定义一个临时变量__mptr,并将其也指向ptr所指向的链表节点const typeof(((type *)0)->member)*__mptr = (ptr);// 步骤3:计算member字段距离type中第一个字段的距离,也就是type地址和member地址之间的差// offset(type, member)也是一个宏,定义如下:#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)// 步骤4:将__mptr的地址 - type地址和member地址之间的差// 其实也就是获取type的地址步骤1很好理解,就是强制类型转换。
步骤2中的typeof()的用法说明:
//把y定义成x指向的数据类型:typeof(*x) y;
步骤3:(TYPE *)0,将 0 强制转换为 TYPE 型指针,记 p = (TYPE *)0,p是指向TYPE的指针,它的值是0。那么 p->MEMBER 就是 MEMBER 这个元素了,而&(p->MEMBER)就是MENBER的地址,而基地址为0,这样就巧妙的转化为了TYPE中的偏移量。再把结果强制转换为size_t型的就OK了,size_t其实也就是int。
typedef __kernel_size_t size_t;
typedef unsigned int __kernel_size_t;
步骤4就是为了获得type的地址。
通过container_of()宏,我们定义一个简单的函数就可以返回包含list_head的父类型结构体:
#define list_entry(ptr, type, member) \container_of(ptr, type, member)因为我们获得一个指向链表结构的指针通常是无用的,我们要操作的是用户数据,是一个指向包含list_head的结构体指针,如之前的student结构体。而通过宏定义container_of()就可以让我们获得该结构体的首地址。
- Linux内核数据结构之链表
- linux内核数据结构之链表
- linux内核数据结构之链表
- linux内核数据结构之链表
- linux内核数据结构之链表
- linux内核数据结构之链表
- linux内核系列(二)内核数据结构之链表
- linux内核数据结构链表
- linux内核数据结构之双向循环链表struct list_head
- Linux内核数据结构之链表list.h
- linux内核里的数据结构之双向链表
- linux内核 路由fib表之数据结构
- linux内核 路由缓存表之数据结构
- 内核数据结构之链表
- 内核数据结构之链表
- 内核数据结构之链表
- 深入浅出linux之内核数据结构
- linux内核数据结构之kfifo
- csdn飞鸽传书 打了七天七夜
- asp.net页面类
- 抽象类与接口的区别(整理)
- 让Category支持添加属性与成员变量
- C#扫描指定IP端口
- Linux内核数据结构之链表
- linux sort,uniq,cut,wc命令详解
- StartActivity ,onActivityResult,setResult简单运用
- 敏捷开发中的Code Review
- BlazdDS里面一些jar包的功能描述
- Java和MySQL数据类型对应一览
- hdu 4712 2种解发(状态dp| 随机化) 我又相信爱情了~~(第一发)
- FileItem类的常用方法
- IT人员看待和预防癌症十大建议