linux鏈表的使用


鏈表的結構體如下:
<鏈表的初始化>
方法1:
實例:
方法2:
定義和初始化一步到位,實例:
方法2:
使用函數的方式初始化
 
<往鏈表中添加成員>
 
 
list_add傳入new,和head。當head還未加入其它元素的情況下,head->next的值是一個地址,該地址指向head本身:
繼續往添加成員:
 
添加成員不只有一個方向,還可以不斷的往HEAD后面追加(①->②,添加③,可以這樣①->②->③,也可以①->③->②,①這里代表head):
 
 
<鏈表中成員的刪除>
                                第一種情況                                                                                                                                                         第二種情況                                                                            
把自己從原來的鏈表中刪除,加入到新的鏈表中
 
 
<鏈表中的判斷>
判斷鏈表是否為空
 
判斷該成員是否為鏈表的最后一項
 
 
 
<鏈表中的使用>
前面看到的是鏈表自己在“玩”自己,那如何使用鏈表呢?看下面這個宏(這個宏完全可以用在其它情景):
這個宏獲取含有 struct list_head 成員的結構體對象首地址
 
了解list_entry前需要先分析下container_of 
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)    //該宏的作用是獲取結構體成員的相對偏移值
/*
*    ptr             :  成員的指針
*    type         :結構體類型
*    member   :在結構體中成員的名稱
*    返回該成員所在的結構體變量的指針
*/
#define container_of(ptr, type, member) ({          \
const typeof(((type *)0)->member)*__mptr = (ptr);    \
     (type *)((char *)__mptr - offsetof(type, member)); })
 
typeof:獲取括號內對象的類型,需要包含頭文件stddef.h
備注:typeof 是 GNU C 標准里特有的擴展,標准的 ISO C 並沒有這個關鍵字,編譯加入了一個 -std=c90 的選項改成 -std=gnu90
實例如下:
結果:
 
 
 
< 鏈表的遍歷 >
pos是臨時使用的struct list_head指針變量,從鏈表head(head不一定是鏈表頭)中遍歷head后面的所有成員。
也可以換個方向遍歷
關於prefetch的解釋如下,未完全明白!
1.有一個共識是:程序訪問的變量如果都能在系統內存cache中則能提升性能,prefetch是內核中一個預熱內存函數,這樣下次遍歷時就能高效命中內存cache,從而提升程序性能。
2.上面的代碼中遍歷鏈表時下次訪問的內存為pos->next,故在每次遍歷時對pos->next進行預熱,從而提升性能。
 
下面的方法是使用最多的,遍歷鏈表取出一個個包含struct list_head成員的結構體對象的首地址
使用實例:
示意圖如下:
 
鏈表的其它接口暫不分析,有需求再看!
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM