Linux內核中鏈表的設計思路

一般實際項目中的鏈表,節點中存儲的數據其實是一個結構體,這個結構體中包含若干的成員,這些成員加起來構成了我們的節點數據區域。

實際上鍊表操作是相同的,而涉及到數據區域的操作就有不同。

鑑於以上2點,能不能有一種辦法把所有鏈表中操作方法裏共同的部分提取出來用一套標準方法實現,然後把不同的部分留着讓具體鏈表的實現者(編程者)自己去處理呢?

Linux內核中鏈表的設計思路
內核鏈表中自己實現了一個純鏈表(純鏈表就是沒有數據區域,只有前後向指針)的封裝,以及純鏈表的各種操作函數(節點創建、插入、刪除、遍歷······)。這個純鏈表本身的用法是給我們具體鏈表作爲核心來調用。
內核中核心純鏈表的實現在include/linux/list.h文件中。list.h中實現了一個純鏈表的完整封裝,包含節點定義和各種鏈表操作方法。

#include <linux/list.h>

struct driver_info
{
int data;
};

// driver結構體用來管理內核中的驅動
struct driver
{
char name[20]; // 驅動名稱
int id; // 驅動id編號
struct driver_info info; // 驅動信息,
struct list_head head; // 內嵌的內核鏈表成員

分析driver結構體,可知:前三個成員都是數據區域成員(就是我們之前簡化爲int data的東西),第4個成員是一個struct list_head類型的變量,這就是一個純鏈表。

本來driver結構體是沒有鏈表的,也無法用鏈表來管理。但是driver內嵌的head成員本身就是一個純鏈表,所以driver通過head成員給自己擴展了鏈表的功能。

driver通過內嵌的方式擴展鏈表成員,本身不只是有了一個鏈表成員,關鍵是可以通過利用list_head本身事先實現的鏈表的各種操作方法來操作head。

最終效果:我們可以通過遍歷head來實現driver的遍歷;遍歷head的函數在list.h中已經事先寫好了,所以我們內核中去遍歷driver時就不用重複去寫了。

通過操作head來操作driver,實質上就是通過操作結構體的某個成員變量來操作整個結構體變量。這裏面要藉助container_of宏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章