大家都知道linux核心是世界上優秀的軟體之一,作為一款優秀的軟體,其中的許多的設計都精妙之處,十分值得學習和借鑑。今天我們就帶大家看一下核心中的資料結構中一點設計。
開啟核心原始碼中的 include/linux/list.h標頭檔案,就可以看到核心中宣告的一些與鍊錶操作相關的結構體定義和函式介面。核心中使用更多的是雙向迴圈鍊錶。我們就看一看核心中雙向迴圈鍊錶的精妙之處吧。
首先看鍊錶節點的結構體的定義:
struct list_head
#define list_head(name) \
struct list_head name = list_head_init(name)
#define mycontainer_of(memadd, type, memname) \
((struct type*)(((char*)memadd - ((unsigned long)&(((struct type*)0)->memname)))))
void init_list_head(struct list_head *list)
list->next = list;
list->prev = list;
void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
void list_add(struct list_head *new, struct list_head *head)
__list_add(new, head, head->next);
int main(void)
//初始化雙向煉表頭
struct list_head *head = malloc(sizeof(struct list_head));
init_list_head(head);
struct list_head *q;
//初始化資料結構體的值
struct data data[4] = ;
int i;
for ( i = 0; i < 4; i++)
data[i].a = i + 1;
//將資料結構體中的list_head型別成員頭插入到雙向鍊錶中
for(i = 0; i < 4; i++)
list_add(&(data[i].p), head);
//根據結構體的乙個成員位址進而找到整個結構體的位址
for (q = head->next; q != head; q = q->next )
struct data *temp;
temp = mycontainer_of(q, data, p);
printf("%d\n", temp->a);
return 0;
Linux核心中的資料結構與演算法(一)
一,序言 其實想寫這個系列很久了,因為本人工作的關係,平時接觸linux核心很多,從業後很多時候在網上查詢的東西是片面或者不系統的,打算給自己的知識庫進行個整理吧,打算開筆寫這個系列,再加上自己想考研了,算是重新學習,也算鞏固自己的知識吧。如果有什麼錯誤和疏漏,也請看客們給出批評意見,比心比心比心 ...
核心中重要的資料結構
任務鍊錶 task list 流程排程程式為每個活動的流程維護乙個資料塊。這些資料塊儲存在稱為任務列表的鏈結列表中。程序排程程式始終維護乙個指示當前活動程序的當前指標。記憶體對映 memry map 記憶體管理器基於每個程序儲存虛擬位址到實體地址的對映,還儲存有關如何獲取和替換特定頁面的其他資訊。此...
Linux核心中關於資料結構操作的乙個問題
在linux核心中的佇列操作都是通過list head來進行的,list head稱為 宿主結構 的 連線件 但是我們真正需要的是宿主結構,而不是這個連線件,如果我們順著乙個佇列取得了其中一項的list head結構時,又怎樣找到其宿主結構呢?剛開始看核心原始碼時,我對這個問題百思不得其解,後來看了...