linux 内核链表遍历宏 list_for_each_entry list_for_each_entry_safe
看内核代码都会发现,内核链表的操作常用的二个宏list_for_each_entry和list_for_each_entry_safe
循序渐进,先从最底层的函数container_of 函数说起,其内核定义如下:
先看offsetof宏,根据优先级的顺序,最里面的小括号优先级最高,
TYPE *将整型常量0强制转换为TYPE型的指针,且这个指针指向的地址为0,
也就是将地址0开始的一块存储空间映射为TYPE型的对象,
接下来再对结构体中MEMBER成员进行取址,而整个TYPE结构体的首地址是0,
这里获得的地址就是MEMBER成员在TYPE中的相对偏移量。
再将这个偏移量强制转换成size_t型数据(无符号整型)。
所以整个offsetof的功能就是获取MEMBER成员在TYPE型数据中的偏移量。
再看看container_of宏,他首先赋值member成员的指针给__mptr,
然后减去成员在结构体中的相对偏移量,
这样就可以获得对应的结构体的(地址)指针;
从注释可以看出,他的作用是获取结构体实体指针,他其实就是container_of;
进入主题来看list_for_each_entry,宏定义如下所示:
首先需要了解双向链表和链表头的概念:建立一个双向链表通常有一个独立的用于管理链表的链表头,链表头一般是不含有实体数据的,必须用INIT_LIST_HEAD()进行初始化,表头建立以后,就可以将带有数据结构的实体链表成员加入到链表中;链表头和链表的示意如下:
list_for_each_entry宏是一个for循环语句,
for循环的第一个参数就是让(head)->next指向member成员所在数据结构的指针,
也就是将pos初始化为链表头指向的第一个实体链表成员,
for的第三句话通过pos->member.next指针遍历整个实体链表,
当pos->member.next再次指向我们的链表头的时候跳出for循环。
整个过程没有对链表头进行遍历(不需要被遍历),
所以使用list_for_each_entry遍历链表必须从链表头开始。
因此可以看出,list_for_each_entry的功能就是遍历以head为链表头的实体链表,对实体链表中的数据结构进行处理;
相比于list_for_each_entry,list_for_each_entry_safe用指针n对链表的下一个数据结构进行了临时存储,
所以如果在遍历链表的时候需要做删除链表中的当前项操作时,
用list_for_each_entry_safe可以安全的删除,而不会影响接下来的遍历过程(用n指针可以继续完成接下来的遍历,
而list_for_each_entry则无法继续遍历,删除后会导致无法继续遍历)。
linux 内核链表遍历宏 list_for_each_entry list_for_each_entry_safe相关推荐
- Linux内核链表交换节点,[笔记]Linux内核链表:结点的插入、删除以及链表的遍历...
Linux内核链表:结点的插入.删除以及链表的遍历 1. Linux内核链表的核心思想是:在用户自定义的结构A中声明list_head类型的成员p,这样每个结构类型为A的变量a中,都拥有同样的成员p, ...
- linux内核链表分析
一.常用的链表和内核链表的区别 1.1 常规链表结构 通常链表数据结构至少应包含两个域:数据域和指针域,数据域用于存储数据,指针域用于建立与下一个节点的联系.按照指针域的组织以及各个节 ...
- 深入分析 Linux 内核链表--转
引用地址:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 一. 链表数据结构简介 链表是一种常用的组织有序数据 ...
- Linux 内核链表 【转】
原文:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 一. 链表数据结构简介 链表是一种常用的组织有序数据的数 ...
- Linux 内核链表剖析(二十)
上节博客中,我们讲到了 Linux 中的宏定义 offsetof 与 container_of 宏.那么本节我们的课程目标就是一直 Linux 内核链表,使其适用于非 GNU 编译器,分析 Linux ...
- 深入理解Linux内核链表
之前写过的链表文章,再结合这篇,我觉得是一道硬菜. Linux内核链表 C语言,链表 大家五一节日快乐,我知道劳动节大家都辛苦了,吃点硬菜好顶住饿肚子~ #一. 链表数据结构简介 链表是一种常用的组织 ...
- Linux内核--链表结构
一.前言 Linux内核链表结构是一种双向循环链表结构,与传统的链表结构不同,Linux内核链表结构仅包含前驱和后继指针,不包含数据域.使用链表结构,仅需在结构体成员中包含list_head* ...
- linux内核链表以及list_entry--linux内核数据结构(一)
传统的链表实现 之前我们前面提到的链表都是在我们原数据结构的基础上增加指针域next(或者prev),从而使各个节点能否链接在一起, 比如如下的结构信息 typedef struct fox { un ...
- linux 内核链表
linux 内核链表 内核链表 #ifndef __C_LIST_H #define __C_LIST_H#define offsetof(TYPE, MEMBER) ((size_t) &( ...
最新文章
- Kubernetes 日志收集的原理,看这一篇就够了
- ASP.NET比较常用的26个性能优化技巧
- 基于ACE Proactor框架下高并发、大容量吞吐程序设计既最近的一个产品开发总结
- 1071 Speech Patterns (25 分)【难度: 简单 / 知识点: 哈希表 字符串】
- python进程共享内存_Python进程间通信之共享内存
- [转]通过创建一个位图的XY Chart来学习Android绘图类Rect,Paint,Bitmap,Canvas(附源码)...
- java集合学习笔记 ---Collections类对集合的处理
- WebSocket 解决javascript跨域问题一剂良药
- html添加变量参数吗,动态CSS与变量参数? (可能吗?)
- 发光二极管pcb封装图画法_电子元器件认识与使用ZD43 | 贴片74HC138 原理图PCB库 封装尺寸 | 视频教程...
- 美国电脑富农:Frank Soltis
- SAP固定资产模块的表
- 聚看点{青龙面板可跑项目之一}保姆教程
- 局域网内2台ubuntu电脑共享鼠标键盘
- Maya XGen 毛发制作1 - 创建头发纹理
- java lisp,摸索JVM上的LISP[Java编程]
- Linux Command tc 模拟网络延迟和丢包
- myeclipse 修改项目名Tomcat启动项目报错java.lang.IllegalArgumentException: Can't convert argument: null...
- 主机屋免费服务器 – 真的开启服务器免费时代?
- 论创新工场、职业发展、offer如何比较选择、移动互联网【转】