linux 的list_for_each_entry

linux的宏定義提高了代碼的簡潔性,但有時候的命名不夠完美。比如list_for_each_entry,看名字只知道是遍歷list,但一看里面的三個變量參數,有點懵逼。

/**
* list_for_each_entry ?- ? ? ? iterate over list of given type
* @pos: ? ? ? ?the type * to use as a loop cursor.
* @head: ? ? ? the head for your list.
* @member: ? ? the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) ? ? ? ? ? ? ? ? ? ? ? ? ?\
for (pos = list_first_entry(head, typeof(*pos), member); ? ? ? ?\
!list_entry_is_head(pos, head, member); ? ? ? ? ? ? ? ? ? ?\
pos = list_next_entry(pos, member))
誰是given type? 被遍歷的是誰?咋看看不出來。

/**
* list_first_entry - get the first element from a list
* @ptr: ? ? ? ?the list head to take the element from.
* @type: ? ? ? the type of the struct this is embedded in.
* @member: ? ? the name of the list_head within the struct.
*
* Note, that list is expected to be not empty.
*/

#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)

這個宏的comments解釋說是獲取一個list的第一個元素。 但是一看宏定義有點懵,怎么又來一個宏在里面?

/**
* list_entry - get the struct for this entry
* @ptr: ? ? ? ?the &struct list_head pointer.
* @type: ? ? ? the type of the struct this is embedded in.
* @member: ? ? the name of the list_head within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)

這個宏定義看解釋是獲取當前entry的所屬結構體,又來一個宏:

  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. * WARNING: any const qualifier of @ptr is lost.

  8. */

  9. #define container_of(ptr, type, member) ({ \

  10. void *__mptr = (void *)(ptr); \

  11. static_assert(__same_type(*(ptr), ((type *)0)->member) || \

  12. __same_type(*(ptr), void), \

  13. "pointer type mismatch in container_of()"); \

  14. ((type *)(__mptr - offsetof(type, member))); })

?此宏就是,給了一個結構體變量的其中成員變量,而獲取此結構體變量的地址。ptr是成員變量地址,type是結構體類型,member是成員變量在結構體聲明里的名字稱謂。

所以說?list_entry 是獲取ptr所屬的結構體地址。list_first_entry 是獲取(ptr)->next 所在結構體的地址,

而list_for_each_entry里面還有宏:

/**
* list_entry_is_head - test if the entry points to the head of the list
* @pos: ? ? ? ?the type * to cursor
* @head: ? ? ? the head for your list.
* @member: ? ? the name of the list_head within the struct.
*/
#define list_entry_is_head(pos, head, member) ? ? ? ? ? ? ? ? ? ? ? ? ? \
(&pos->member == (head))
這個宏名字取的更敷衍。解釋內容說是為了驗證是不是list的頭指針。 看代碼是驗證pos這個結構體的成員member地址是不是和head一樣。

再看另外一個宏:

/**
* list_next_entry - get the next element in list
* @pos: ? ? ? ?the type * to cursor
* @member: ? ? the name of the list_head within the struct.
*/
#define list_next_entry(pos, member) \
list_entry((pos)->member.next, typeof(*(pos)), member)
解釋內容說是獲取list的下一個成員指針,看代碼是獲取(pos)->member.next 所在結構體的地址。

這樣整體來看:

#define list_for_each_entry(pos, head, member) ? ? ? ? ? ? ? ? ? ? ? ? ?\
for (pos = list_first_entry(head, typeof(*pos), member); ? ? ? ?\ //獲取head->next所在結構體地址給pos
!list_entry_is_head(pos, head, member); ? ? ? ? ? ? ? ? ? ?\//判斷pos的member成員地址是否和head一樣,如果一樣,就跳出循環
pos = list_next_entry(pos, member))? ?//獲取(pos)->member.next 所在結構體的地址

綜上所述,這里遍歷了一個循環鏈表,表頭是head,但是似乎head沒被拿來遍歷到?直接從head->next開始的?遍歷到再次碰到head的地址就結束了,即表明遍歷了一圈了。?member就是鏈表個成員(鏈表類型地址)內含的內容地址。這里head為什么是廢棄的?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/89561.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/89561.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/89561.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

分布式面試點

目錄 1.分布式理論 為什么CAP不可兼得呢? 2.CAP對應的模型和應用 3.Base理論 4,有哪些分布式鎖的案例 5.分布式事務 6.Seata 分布式一致性算法 1. 準備階段(Prepare Phase) 2. 接受階段(Accept Phase) 3. 學習階段&…

Neo4j系列---【Linux離線安裝neo4j】

Linux離線安裝neo4j 1.官方安裝文檔 地址:https://neo4j.com/docs/operations-manual/current/installation/linux/tarball/ 2.如果瀏覽器無法訪問 修改neo4j.conf,開放所有ip訪問 # 允許所有IP地址訪問 server.default_listen_address0.0.0.0 3.創建開機自啟動服務…

SEO長尾關鍵詞核心實戰技巧提升排名

內容概要 本文聚焦于SEO長尾關鍵詞的核心實戰技巧,旨在幫助讀者精準鎖定目標用戶的搜索意圖,從而提升網站自然排名和獲取精準流量。文章將從基礎概念入手,系統解析如何挖掘高轉化率的長尾關鍵詞,優化內容結構以增強搜索可見度&…

當OT遇見IT:Apache IoTDB如何用“時序空間一體化“技術破解工業物聯網數據孤島困局?

目錄 一. 什么是時序數據庫? 二. 時序數據庫的選型要素 性能指標 架構能力 數據模型與查詢能力 安全與權限控制 部署與運維能力 三 Apache IoTDB 簡介及安裝使用: 安裝準備教程 檢查 Java 版本 下載與安裝 下載 IoTDB 解壓文件 配置環境變量 啟動…

一文講透HTML語義化標簽

文章目錄語義化標簽概述HTML標簽及其含義常見HTML5語義化標簽語義化標簽對搜索引擎(SEO)的影響提升搜索引擎排名增強可訪問性改善用戶體驗語義化標簽案例各標簽作用說明語義化標簽概述 HTML 語義化是指使用恰當的標簽來準確表達內容的結構和含義&#x…

Django 實戰:靜態文件與媒體文件從開發配置到生產部署

文章目錄一、靜態文件與媒體文件區別與聯系配置開發環境配置二、媒體文件實戰實戰場景定義模型定義序列化器定義視圖實戰效果三、生產部署說明收集靜態文件Nginx配置示例OpenResty配置示例一、靜態文件與媒體文件 區別與聯系 在 Django 項目中,靜態文件&#xff0…

Python自動化分析知網文獻:爬取、存儲與可視化

1. 引言 在當今的學術研究和大數據分析領域,高效獲取和分析學術文獻數據具有重要意義。中國知網(CNKI)作為國內最權威的學術資源平臺之一,包含了海量的期刊論文、會議論文和學位論文。然而,手動收集和分析這些數據不僅…

Python應用指南:使用PyKrige包實現ArcGIS的克里金插值法

先了解什么是克里金插值?克里金插值(Kriging interpolation)是一種基于統計學和空間相關性的高級空間插值方法,廣泛應用于地理信息系統(GIS)、地質勘探、環境科學、氣象學等領域。它由南非礦業工程師丹尼爾…

Redis原理之哨兵機制(Sentinel)

上篇文章: Redis原理之主從復制https://blog.csdn.net/sniper_fandc/article/details/149141103?fromshareblogdetail&sharetypeblogdetail&sharerId149141103&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目錄 1 哨兵機制恢…

uniapp打包成 apk

1. 先把項目打包成 index.html 上傳到寶塔服務器,關聯到域名 2.然后再用hbuilder新建一個 基礎模板的 uniapp 3.再修改代碼,采用iframe方式打包 pages/index/index <template><web-view v-if="showWebView" :src="webViewSrc" @message=&qu…

RPG57.創建玩家拾取物品類一:創建可拾取物品類的基類

1。新建一個基類&#xff0c;用于玩家可拾取物品的父類然后// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "Components/SphereComponent.h" #include "GameFramewo…

k8s之持久化存儲流程

K8s 中的 Pod 在掛載存儲卷時需經歷三個的階段&#xff1a;Provision/Delete&#xff08;創盤/刪盤&#xff09;、Attach/Detach&#xff08;掛接/摘除&#xff09;和 Mount/Unmount&#xff08;掛載/卸載&#xff09; Provisioning Volumes 時序流程詳解 一、流程圖 sequenc…

python學智能算法(二十四)|SVM-最優化幾何距離的理解

引言 前序學習過程中&#xff0c;已經對幾何距離的概念有了認知&#xff0c;學習鏈接為&#xff1a;幾何距離 這里先來回憶幾何距離δ的定義&#xff1a; δmin?i1...myi(w∥w∥?xib∥w∥)\delta \min_{i1...m}y_{i}(\frac{w}{\left \| w \right \|}\cdot x_{i}\frac{b}{\le…

創建游戲或互動體驗:從概念到實現的完整指南

Hi&#xff0c;我是布蘭妮甜 &#xff01;在數字時代&#xff0c;游戲和互動體驗已成為娛樂、教育和商業領域的重要組成部分。本文將帶你了解如何使用JavaScript創建引人入勝的游戲和互動體驗&#xff0c;從基礎概念到實際實現。 文章目錄一、游戲開發基礎1.1 游戲循環1.2 游戲…

SpringMVC + Tomcat10

1. Tomcat 10的servlet包路徑變了&#xff0c;javax -> jakarta 2. DispatcherServlet從Spring6 才開始使用jakarta.servlet.http.Servlet 3. Spring6 需要JDK 17 1. pom <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org…

Django `transaction.atomic()` 完整使用指南

目錄 #概述#基本用法#事務一致性保障機制#破壞一致性的常見場景#高級用法#最佳實踐#診斷與調試#附錄 概述 transaction.atomic() 是 Django 提供的數據庫事務管理工具&#xff0c;用于確保一系列數據庫操作要么全部成功提交&#xff0c;要么全部回滾&#xff0c;維護數據的一致…

UDP協議的端口161怎么檢測連通性

UDP 端口 161 (SNMP) 連通性檢測的專業指南 UDP 161 端口是 SNMP (Simple Network Management Protocol) 服務的標準端口。由于其無連接特性&#xff0c;檢測需要特殊方法。以下是全面的檢測方案&#xff1a; 一、專業檢測方法 1. 使用 SNMP 專用工具&#xff08;推薦&#xff…

進階數據結構:紅黑樹

嘿&#xff0c;各位技術潮人&#xff01;好久不見甚是想念。生活就像一場奇妙冒險&#xff0c;而編程就是那把超酷的萬能鑰匙。此刻&#xff0c;陽光灑在鍵盤上&#xff0c;靈感在指尖跳躍&#xff0c;讓我們拋開一切束縛&#xff0c;給平淡日子加點料&#xff0c;注入滿滿的pa…

如何上傳github(解決git的時候輸入正確的賬號密碼,但提示認證失敗)

如何上傳github文件&#xff0c;刪除文件 1.重點 GitHub 從 2021 年 8 月 13 日起移除了對密碼認證的支持。你需要使用個人訪問令牌(Personal Access Token, PAT)或 SSH 密鑰來進行認證。 2.生成SSH key 進入設置點擊New SSH Key名字隨便取&#xff0c;可以自己方便記3.上傳文件…

多級緩存架構與熱點探測系統核心技術解析

多級緩存架構與熱點探測系統核心技術解析 &#x1f4cc; 一、多級緩存架構 1. 為什么需要多級緩存&#xff1f; ? 本地緩存優勢&#xff1a; &#x1f680; 減少網絡請求&#xff0c;提升訪問性能&#x1f310; 分布式系統中天然具有分布式緩存特性?? 有效降低遠程緩存&…