1. 程式人生 > >Linux核心中連結串列的設計思路

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巨集