linux 内核list head,Linux内核之list_head.pdf
Linux內核之list_head.pdf
一、 鏈表數據結構簡介
/bbs/thread-995286-1-3.html
鏈表是一種常用的組織有序數據的數據結構,它通過指針將一系列數據節點連接成一條數據鏈,
是線性表的一種重要實現方式。相對于數組,鏈表具有更好的動態性,建立鏈表時無需預先知道
數據總量,可以隨機分配空間,可以高效地在鏈表中的任意位置實時插入或刪除數據。鏈表的開
銷主要是訪問的順序性和組織鏈的空間損失。
通常鏈表數據結構至少應包含兩個域:數據域和指針域,數據域用于存儲數據,指針域用于建立
與下一個節點的聯系。按照指針域的組織以及各個節點之間的聯系形式,鏈表又可以分為單鏈表 、
雙鏈表、循環鏈表等多種類型,下面分別給出這幾類常見鏈表類型的示意圖:
1. 單鏈表
圖1 單鏈表
單鏈表是最簡單的一類鏈表,它的特點是僅有一個指針域指向后繼節點(next),因此,對單鏈
表的遍歷只能從頭至尾(通常是NULL空指針)順序進行。
2. 雙鏈表
圖2 雙鏈表
通過設計前驅和后繼兩個指針域,雙鏈表可以從兩個方向遍歷,這是它區別于單鏈表的地方。如
果打亂前驅、后繼的依賴關系,就可以構成"二叉樹";如果再讓首節點的前驅指向鏈表尾節點、
尾節點的后繼指向首節點(如圖2中虛線部分),就構成了循環鏈表;如果設計更多的指針域,
就可以構成各種復雜的樹狀數據結構。
3. 循環鏈表
循環鏈表的特點是尾節點的后繼指向首節點。前面已經給出了雙循環鏈表的示意圖,它的特點是
從任意一個節點出發,沿兩個方向的任何一個,都能找到鏈表中的任意一個數據。如果去掉前驅
指針,就是單循環鏈表。
在Linux內核中使用了大量的鏈表結構來組織數據,包括設備列表以及各種功能模塊中的數據
組織。這些鏈表大多采用在[include/linux/list.h]實現的一個相當精彩的鏈表數據結構。本文
的后繼部分就將通過示例詳細介紹這一數據結構的組織和使用。
二、 Linux 2.6內核鏈表數據結構的實現
盡管這里使用2.6內核作為講解的基礎,但實際上2.4內核中的鏈表結構和2.6并沒有什么區別。
不同之處在于2.6擴充了兩種鏈表數據結構:鏈表的讀拷貝更新(rcu)和HASH鏈表(hlist)。
這兩種擴展都是基于最基本的list結構,因此,本文主要介紹基本鏈表結構,然后再簡要介紹一
下rcu和hlist。
鏈表數據結構的定義很簡單(節選自[include/linux/list.h],以下所有代碼,除非加以說明,
其余均取自該文件):
struct list_head {
struct list_head *next, *prev;
};
list_head結構包含兩個指向list_head結構的指針prev和next,由此可見,內核的鏈表具
備雙鏈表功能,實際上,通常它都組織成雙循環鏈表。
和第一節介紹的雙鏈表結構模型不同,這里的list_head沒有數據域。在Linux內核鏈表中,
不是在鏈表結構中包含數據,而是在數據結構中包含鏈表節點。
在數據結構課本中,鏈表的經典定義方式通常是這樣的(以單鏈表為例):
struct list_node {
struct list_node *next;
ElemType data;
};
因為ElemType的緣故,對每一種數據項類型都需要定義各自的鏈表結構。有經驗的C++程序
員應該知道,標準模板庫中的采用的是C++ Template,利用模板抽象出和數據項類型
無關的鏈表操作接口。
在Linux內核鏈表中,需要用鏈表組織起來的數據通常會包含一個 struct list_head成員,例
如在[include/linux/netfilter.h]中定義了一個nf_sockopt_ops結構來描述Netfilter為某一
協議族準備的getsockopt/setsockopt接口,其中就有一個(struct list_head list)成員,
各個協議族的nf_sockopt_ops結構都通過這個list成員組織在一個鏈表中,表頭是定義在
[net/core/netfilter.c]中的nf_sockopts(struct list_head)。從下圖中我們可以看到,這種
通用的鏈表結構避免了為每個數據項類型定義自己的鏈表的麻煩。Linux的簡捷實用、不求完美
和標準的風格,在這里體現得相當充分。
圖3 nf_socko
總結
以上是生活随笔為你收集整理的linux 内核list head,Linux内核之list_head.pdf的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Wide Deep模型的理解及实战(T
- 下一篇: 学海无涯!史上最全的《Android面试