【Linux】list_for_each_entry用法

2023-11-07

参考:

http://blog.sina.com.cn/s/blog_5e99b41e0100rxgf.html

http://hi.baidu.com/shiftedmind/blog/item/1a7c8381e6a67fa56d8119da.html

         在Linux内核源码中,经常要对链表进行操作,其中一个很重要的宏是list_for_each_entry:

意思大体如下:

         假设下面几个结点,则第一个member代表head,list_for_each_entry的作用就是循环遍历每一个pos中的member子项。

list_for_each_entry应用:

         它实际上是一个 for 循环,利用传入的 pos 作为循环变量,从表头 head 开始,逐项向后(next 方向)移动 pos,直至又回head(prefetch() 可以不考虑,用于预取以提高遍历速度 )。 

在程序中的使用如下:

list_for_each_entry(pos , head,member)

{       

………………

      addr =    pos;  //对返回值pos的操作,这样更容易去理解list_for_each_entry,可以把它看作for()循环

………………

}


宏list_for_each_entry的实现:

[cpp]  view plain  copy
  1. /** 
  2.  * list_for_each_entry  -   iterate over list of given type 
  3.  * @pos:    the type * to use as a loop cursor. 
  4.  * @head:   the head for your list. 
  5.  * @member: the name of the list_struct within the struct. 
  6.  */  
  7. #define list_for_each_entry(pos, head, member)              \  
  8.     for (pos = list_entry((head)->next, typeof(*pos), member);   \  
  9.          prefetch(pos->member.next), &pos->member != (head);  \  
  10.          pos = list_entry(pos->member.next, typeof(*pos), member))  

对程序中for循环的三步分析:

(1),pos = list_entry((head)->next, typeof(*pos), member)

         pos相当于循环中返回的循环变量,这里就是返回一个结构体指针。实现过程如下:

函数list_entry():

[cpp]  view plain  copy
  1. /** 
  2.  * list_entry - get the struct for this entry 
  3.  * @ptr:    the &struct list_head pointer. 
  4.  * @type:   the type of the struct this is embedded in. 
  5.  * @member: the name of the list_struct within the struct. 
  6.  */  
  7. #define list_entry(ptr, type, member) \  
  8.     container_of(ptr, type, member)  

跟进:container_of这个函数

         这个不做重点分析,这个函数的做用是:它的作用显而易见,那就是根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针。

[cpp]  view plain  copy
  1. /** 
  2.  * container_of - cast a member of a structure out to the containing structure 
  3.  * @ptr:    the pointer to the member. 
  4.  * @type:   the type of the container struct this is embedded in. 
  5.  * @member: the name of the member within the struct. 
  6.  * 
  7.  */  
  8. #define container_of(ptr, type, member) ({          \  
  9.     const typeof(((type *)0)->member)*__mptr = (ptr);    \  
  10.              (type *)((char *)__mptr - offsetof(type, member)); })  

所以list_entry()的作用为:如上图所示,可以以通过已知的指向member子项的指针,获得整个结构体的指针(地址)

(2),   prefetch(pos->member.next),&pos->member!= (head);  

         prefetch的含义是告诉cpu那些元素有可能马上就要用到,告诉cpu预取一下,这样可以提高速度用于预取以提高遍历速度;

         &pos->member !=(head)  ,这个判断循环条件。

(3),  pos= list_entry(pos->member.next, typeof(*pos), member)) 

         和第(1)实现相似,用于逐项向后(next 方向)移动 pos

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】list_for_each_entry用法 的相关文章

  • Qt 使用布局管理器,控件大小未能自适应变化

    问题 使用布局管理器管理子部件 使用了QVHlayout管理器 发现控件大小固定 即使通过拖动窗口也不能改变控件的大小 布局管理器不是自动控制部件的大小吗 为什么没有生效 如图所示 解决办法 对子部件添加延申策略 setSizePolicy
  • imx6ull开发板,usb免驱摄像头的配置

    在 dev下面 只能找到video0 说明开发板并没有识别出有新连接进来的摄像头 需要在内核中 配置支持UVC标准的USB驱动 重新配置即可
  • VMWare里Linux的网络配置

    今天终于把十几天前安装在VMWare里的Linux的网络配置搞定了 高兴啊 刚使用虚拟机时 就被它神奇的虚拟功能所着迷 因为一直想在电脑里装Linux 可是由于它与Windows的不兼容 怕一安装就把原来的系统破坏 但是在虚拟机里真的能很好
  • linux 多线程 pthread_cond_wait(&cond,&mutex)理解

    pthread cond wait 用于阻塞一个线程 知道有信号唤醒它 下面是一个简单的例子 我们可以从程序的运行来了解条件变量的作用 pthread cond wait c include
  • smbus电池信息读取

    smbus协议的智能电池 我们可以使用i2c的读写方式获取ic信息 也可以使用smbus协议的接口获取 编译方法 arm none linux gnueabi gcc batterygetdemo c o batterygetdemo 编译
  • 13.linux进程基础

    一 进程基础 基础概念 关于进程和线程的基本概念在操作系统中早已学过 可以概括为一下几点 根本区别 进程是操作系统资源分配的基本单位 而线程是处理器任务调度和执行的基本单位 资源开销 每个进程都有独立的代码和数据空间 程序上下文 程序之间的
  • 17.linuxGPIO应用编程

    除了LED类设备可以通过sysfs文件系统控制以外 还可以使用该虚拟文件系统控制GPIO的高低电平 输入以及中断检测 一 GPIO控制高低电平 进入目录sys class gpio下可以看到有如下文件 其中gpiochip0对应硬件的GPI
  • 15.线程同步的几种方法

    一 为什么需要线程同步 线程同步通常是出现在多线程环境下的问题 对于多个线程同时访问的共享内存中的变量 如果不进行保护 就会导致一些列数据出错问题 以下图为例 假设线程A在第一次读取变量的值为10 每次写周期会将变量A加5 理论上当线程A完
  • #if defined(__cplusplus)

    由于C 编译器需要支持函数的重载 会改变函数的名称 因此dll的导出函数通常是标准C定义的 这就使得C和C 的互相调用变得很常见 但是有时可能又会直接用C来调用 不想重新写代码 让标准C编写的dll函数定义在C和C 编译器下都能编译通过 通
  • 【Linux】list_for_each_entry用法

    参考 http blog sina com cn s blog 5e99b41e0100rxgf html http hi baidu com shiftedmind blog item 1a7c8381e6a67fa56d8119da h
  • serial消息查看指令

    cat proc tty driver serial 查看当前设备上的所有串口的接收和发送的数据
  • Qt-configure配置选项

    这个页面给出了一个简短的 当使用configure脚本或configure exe二进制构建Qt时的各种不同的可用选项 当使用默认选项构建Qt 只需如下所示的从命令行调用configure 在Linux Mac OS X和Unix平台下构建
  • 启动 GDB 调试

    使用 GDB 调试程序一般有三种方式 gdb filename gdb attach pid gdb filename corename 这也对应着本节课的核心内容 直接调试目标程序 附加进程 调试 core 文件 接下来我们逐一讲解 直接
  • glob函数的使用

    glob库函数用于Linux文件系统中路径名称的模式匹配 即查找文件系统中指定模式的路径 注意 这不是正则表达式匹配 虽然有些相似 但还是有点差别 glob函数原型 include
  • Qt中正则表达式

    TOC 不积跬步 无以至千里 Qt中正则表达式 正则表达式 regular expression 就是在一个文本中匹配子字符串的一种模式 pattern 它可以简写为 regexp 一个regexp主要应用在以下几个方面 验证 一个rege
  • printk,printf 打印调试

    includelinux kernel h define KERN EMERG lt 0 gt 紧急事件消息 系统崩溃之前提示 表示系统不可用 define KERN ALERT lt 1 gt 报告消息 表示必须立即采取措施 define
  • 【c程序】expected identifier before numeric constant错误

    在linux开发中 出现类似error expected identifier before numeric constant错误 原因 定义的enum结构体与其它处的宏定义有冲突 举例说明 在文件a h中 define TRUE 1 在文
  • 例说hg(六)———— hg branch 创建分支

    开篇 branch 分支 應該也是 Hg 最重要的技能之一 在一個多人專案的開發過程中我們有時候要開發新功能 有時候是要修正某個Bug 有時候想要測試某個特異功能能不能 work 這時候我們通常都會從主 branch 再開出一條新的 bra
  • 嵌入式开发之移植MQTT到RK3568

    目录 前言 一 下载qmqtt源码 二 编译库文件 三 移植到RK3568 3 1 移植动态库libQt5Qmqtt 四 联机测试 4 1 制作demo 4 1 1 创建demo新项目 4 1 2 添加network模块支持 4 1 3 添
  • LINUX CGI

    为什么要进行CGI编程 在HTML中 当客户填写了表单 并按下了发送 submit 按钮后 表单的内容被发送到了服务器端 一般的 这时就需要有一个服务器端脚本来对表单的内容进行一些处理 或者是把它们保存起来 或者是按内容进行一些查询 或者是

随机推荐

  • 合宙Air724UG LuatOS-Air LVGL API控件-图片 (Image)

    图片 Image 图片IMG是用于显示图像的基本对象类型 图像来源可以是文件 或者定义的符号 示例代码 创建图片控件 img lvgl img create lvgl scr act nil 设置图片显示的图像 lvgl img set s
  • C# 执行 .bat 文件

    string path E a bat Process pro new Process FileInfo file new FileInfo path pro StartInfo WorkingDirectory file Director
  • 在react hook里使用mobx(配置mobx依赖)

    在powershell里安装依赖 直接npm i mobx或者npm i mobx react是会报错的 npm i mobx mobx react save save是下载到 dependencies 里 npm i mobx react
  • 图像边缘及matlab实现

    图像边缘是图像的重要特征 是图像中特性 如像素灰度 纹理等 分布的不连续处 图像周围特性有阶跃变化或屋脊状变化的那些像素集合 图像的边缘部分集中了图像的大部分信息 一幅图像的边缘结构与特点往往是决定图像特质的重要部分 图像边缘的另一个定义是
  • Spring Boot + Vue的网上商城之物流系统实现

    Spring Boot Vue的网上商城之物流系统实现 思路 当构建一个物流系统时 我们可以按照以下步骤进行 设计数据模型 首先确定系统中需要存储的数据 例如物流公司信息 物流订单信息等 根据需求设计相应的数据模型 包括实体类和数据库表结构
  • 软件工程考试归纳知识点

    软件工程 第一章 什么是软件 软件是计算机系统中与硬件子系统相互依存的另一个子系统 是一个包含程序及其文档资料的完整集合 提供了用户与硬件子系统之间的接口 软件的特征 1 软件固有的特性 复杂性 抽象性 依赖性 软件使用特性 2 软件生产特
  • Python之可变参数,*参数,**参数,以及传入*参数,进行解包

    1 定义了一个需要两个参数的函数 def print str first second print first print second if name main print str hello world 如果传一个参数调用 print
  • Blink 帮助文档 编译

    个人使用的是Centos7 1 安装rvm 参考 http rvm io rvm install gpg keyserver hkp pool sks keyservers net recv keys 409B6B1796C275462A1
  • Rocksdb Compaction原理

    概述 compaction主要包括两类 将内存中imutable 转储到磁盘上sst的过程称之为flush或者minor compaction 磁盘上的sst文件从低层向高层转储的过程称之为compaction或者是major compac
  • c++中引用及指针详解

    这里写目录标题 1 指针 1 1 什么是指针 指针的本质 指针与地址 程序中如何声明指针以及如何使用运算符 和 1 2 指针有什么作用 指针与函数参数 2 引用 2 1 什么是引用 2 2 引用的规则 2 3 引用和数组 引用的数组 非法
  • 在linux中,使用sh文件脚本启动jar项目

    使用方法 sh 执行脚本 sh start stop restart status sh文件内容 APP NAME XXXX jar 使用说明 用来提示输入参数 usage echo Usage sh 执行脚本 sh start stop
  • SpringBoot HTTP接口GET请求

    HTTP接口get请求 注解使用 1 RequestMapping 来映射请求 也就是通过它来指定控制器可以处理哪些URL请求 2 PathVariable 将 URL 中的占位符绑定到控制器的处理方法的参数中 占位符使用 括起来 3 Ge
  • 完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。 它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。 例如:28,它有约数1 style="">

    题目 完全数 Perfect number 又称完美数或完备数 是一些特殊的自然数 它所有的真因子 即除了自身以外的约数 的和 即因子函数 恰好等于它本身 例如 28 1 2 4 7 14 28 给定数计算n以内完全数的个数 计算范围 0
  • 《PRML》学习笔记2.2——多项式分布和狄利克雷分布

    上回讲完了伯努利分布 二项分布和Beta分布 以及从最大似然估计的非参数化思想和引入共轭先验 使得参数变成一个变量 建模求解的参数化方法两方面介绍了求解模型参数的方法 没有读过的朋友可以参考 PRML 学习笔记2 1 伯努利分布 二项分布和
  • three.js应用cannon物理引擎设置物体的相互作用

    一 cannon物理引擎介绍 cannon官网地址 https pmndrs github io cannon es Cannon js 是一个基于 JavaScript 的开源 3D 物理引擎 可以用于开发和模拟真实世界中的物理效果 它提
  • 机器学习-分类-朴素贝叶斯算法

    三 朴素贝叶斯算法 朴素贝叶斯算法是基于贝叶斯定理与特征条件独立性假设的分类方法 1 原理 1 贝叶斯定理 2 特征条件独立性假设 给定一个数据集 x y 每个样本x包含n维特征 类标签集合y包含N个类别 现给定一个新样本x 需要判断它属于
  • grub rescue修复方法

    问题描述 开机显示 GRUB loading error unknow filesystem grub rescue gt 造成该问题的原因 1 直接在window下格式化ubuntu的分区 2 调整磁盘 利用工具合并 修改 删除分区 是磁
  • python爬虫封装函数_爬虫验证码的几种处理方式,已封装成类,文章末尾有源码!...

    最近事情其实挺多了 打了一下蓝桥杯的比赛 还在准备着一些证书的考试 关于爬虫之类的博客都搁着了一段时间了 关于我自己确实有点退步了 实属不该 其实我自己也是在想 大三了 到底我是要去考研 还是依然像这样更新换代的学技术 再或者 继续钻爬虫这
  • Oracle中char、varchar、varchar2的区别

    1 从字符长度上来分 var可以保存2000个字符 varchar 同样保存2000个字符 varchar 保存4000个字符 2 从字符长度是否可变上来分 var和varchar长度一样 但是varchar是可变的var是不可变的 var
  • 【Linux】list_for_each_entry用法

    参考 http blog sina com cn s blog 5e99b41e0100rxgf html http hi baidu com shiftedmind blog item 1a7c8381e6a67fa56d8119da h