Linux核心學習之鍊錶

2021-08-26 11:52:54 字數 2149 閱讀 1258

文章參照任橋位linux核心修煉之道3.6節編寫。

1. 鍊錶的定義

這個跟我們在課本上學習的一樣,相當簡單。包括了乙個前項指標,和後項指標。是不是有點不對勁?不錯,竟然沒有資料域!不急,我們慢慢看。

struct list_head ;

沒有資料是核心鍊錶的一大特色,因為他採用的方式比較特殊,他不是用鍊錶來包含資料的,而是讓資料項反回來包含鍊錶的。剛開始多多少少有點難以理解,下面會解釋的。

2. 鍊錶的的定義和初始化

(1)採用list_head巨集在編譯時靜態初始化

#definelist_head_init(name) #definelist_head(name) \ struct list_head name =list_head_init(name)

list_head_init是巨集定義,也就是說在定義的時候把他擴充套件一下就很容易理解了。比如初始化語句為

list_head(event_list),可以理解為

struct list_headevent_list =

結構體大家應該還沒有忘記吧,裡面有一條可以按照成員順序在定義時對其進行初始化,所以這句就很明顯了。目的是把next prev指標初始化指向它本身。

(2)採用init_list_head函式在執行時動態初始化,這個目的一眼就看出來了,同上面一樣。

static inline voidinit_list_head(struct list_head *list)

3. 判斷鍊錶是否為空的操作,即是判斷是否指向自己本身而已

static inline intlist_empty(const struct list_head *head)

4.插入操作,學過鍊錶操作的都看得懂,看不懂的自己去學煉表去。

static inline void__list_add(struct list_head *new, struct list_head *prev, struct list_head *next) static inline voidlist_add(struct list_head *new, struct list_head *head) static inline voidlist_add_tail(struct list_head *new, struct list_head *head)

5. 移動、刪除等等類似,主要講遍歷!遍歷的精彩部分在於鍊錶是被資料報含著的,如何通過被包含的鍊錶取出包含他的資料(有點拗口)

比如書上舉的那個例子:

struct list_head*tmp; struct usb_hub *hub; tmp =hub_event_list.next; hub = list_entry(tmp,struct usb_hub, event_list);

資料結構是usb_hub,裡面包含著乙個list_head資料項,然後現在有乙個list_head的鍊錶hub_event_list,要取出裡面包含hub_event_list.next的資料usb_hub。這就是上述**的功能。最重要的函式為list_entry,**如下:

#definelist_entry(ptr, type, member) \ container_of(ptr, type, member)

這個不用解釋,他呼叫的是container_of(ptr, type, member),直接看這個巨集定義

#definecontainer_of(ptr, type, member) () #defineoffsetof(type, member) ((size_t) &((type *)0)->member)

這個看起來比較費力。需要一步步理解。首先,巨集定義不是函式,巨集定義的引數不受函式的限制,所以在list_entry和container_of的第二個引數都是以資料型別做引數的。另外gcc有乙個對iso c的擴充套件,就是他支援typeof操作,具體可以看這裡:主要看最後講解typeof。簡單來看他就是可以返回乙個型別,基本可以用在你想用的任何時候。

接著上面的例子來解釋:

type為usb_hub,type *就是usb_hub*,0可以理解為null,也就是usb_hub->event_list就是((type *)0)->member。一整句就是定義了乙個list_head型別的常量指標,指向了引數的event_list。然後下一步是通過計算偏移量,讓這個指標減去這個偏移量,即減去後的指標指向的可以看作是乙個usb_hub的資料結構,至此就把usb_hub取出來了。

Linux核心學習之鍊錶

文章參照任橋位linux核心修煉之道3.6節編寫。1.鍊錶的定義 這個跟我們在課本上學習的一樣,相當簡單。包括了乙個前項指標,和後項指標。是不是有點不對勁?不錯,竟然沒有資料域!不急,我們慢慢看。struct list head 沒有資料是核心鍊錶的一大特色,因為他採用的方式比較特殊,他不是用鍊錶來...

linux核心學習 核心鍊錶

資料結構是程式設計中很重要的一部分.鍊錶是一種資料結構,程式設計中,我們為了實現鍊錶這種資料結構,常常需要完成他的初始化,新增,遍歷,新增,刪除等功能.針對n多種鍊錶來講,除了內容不同外,但這些 新增,刪除,遍歷操作其實都是可以寫成公共 的,不必每次需要實現一種鍊錶,就重新寫一遍新增,刪除,遍歷的操...

Linux核心學習

交叉工具鏈 核心相關知識 linux系統的構成 使用者空間 核心空間 思考 為什麼劃分為兩個層次?目的其實是為保護作業系統,防止應用程式的異常導致作業系統崩潰。核心空間與使用者空間是程式執行的兩種不同狀態,通過系統呼叫和硬體中斷能夠完成從使用者空間到核心空間的轉移。那麼linux的核心由哪些構成呢?...