内核链表
以下內(nèi)容源于朱有鵬《物聯(lián)網(wǎng)大講堂》課程的學(xué)習(xí),如有侵權(quán),請告知刪除。
一、linux內(nèi)核鏈表
1、普通鏈表的數(shù)據(jù)區(qū)域的局限性
- 之前定義數(shù)據(jù)區(qū)域時直接int data,我們認為我們的鏈表中需要存儲的是一個int類型的數(shù)。但是實際上現(xiàn)實編程中鏈接中的節(jié)點不可能這么簡單,而是多種多樣的。
- 一般實際項目中的鏈表,節(jié)點中存儲的數(shù)據(jù)其實是一個結(jié)構(gòu)體,這個結(jié)構(gòu)體中包含若干的成員,這些成員加起來構(gòu)成了我們的節(jié)點數(shù)據(jù)區(qū)域。
2、一般性解決思路:即把數(shù)據(jù)區(qū)封裝為一個結(jié)構(gòu)體
(1)因為鏈表實際解決的問題是多種多樣的,所以內(nèi)部數(shù)據(jù)區(qū)域的結(jié)構(gòu)體構(gòu)成也是多種多樣的。
- 這樣也導(dǎo)致了不同程序當中的鏈表總體構(gòu)成是多種多樣的。
- 我們無法通過一套泛性的、普遍適用的操作函數(shù)來訪問所有的鏈表,意味著我們設(shè)計一個鏈表就得寫一套鏈表的操作函數(shù)(節(jié)點創(chuàng)建、插入、刪除、遍歷……)。
(2)實際上深層次分析會發(fā)現(xiàn)
- 不同的鏈表雖然這些方法不能通用需要單獨寫,但是實際上內(nèi)部的思路和方法是相同的,只是函數(shù)的局部地區(qū)有不同。
- 實際上鏈表操作是相同的,而涉及到數(shù)據(jù)區(qū)域的操作就有不同
(3)問題
- 能不能有一種辦法把所有鏈表中操作方法里共同的部分提取出來用一套標準方法實現(xiàn),然后把不同的部分留著讓具體鏈表的實現(xiàn)者自己去處理。
3、內(nèi)核鏈表的設(shè)計思路
(1)內(nèi)核鏈表中實現(xiàn)一個純鏈表的封裝,以及純鏈表的各種操作函數(shù)
- 純鏈表就是沒有數(shù)據(jù)區(qū)域,只有前后向指針;
- 各種操作函數(shù)是節(jié)點創(chuàng)建、插入、刪除、遍歷。
- 這個純鏈表本身自己沒有任何用處,它的用法是給我們具體鏈表作為核心來調(diào)用。
4、list.h文件簡介
(1)內(nèi)核中核心純鏈表的實現(xiàn)在include/linux/list.h文件中
(2)list.h中就是一個純鏈表的完整封裝,包含節(jié)點定義和各種鏈表操作方法。
二、內(nèi)核鏈表的基本算法和使用簡介
1、內(nèi)核鏈表的節(jié)點創(chuàng)建、刪除、遍歷等
2、內(nèi)核鏈表的使用實踐
(1)問題:內(nèi)核鏈表只有純鏈表,沒有數(shù)據(jù)區(qū)域,怎么使用?
- 使用方法是將內(nèi)核鏈表作為將來整個數(shù)據(jù)結(jié)構(gòu)的結(jié)構(gòu)體的一個成員內(nèi)嵌進去。類似于公司收購,實現(xiàn)被收購公司的功能。
- 這里面要借助container_of宏。
#include <linux/list.h>struct driver_info {int data; };// driver結(jié)構(gòu)體用來管理內(nèi)核中的驅(qū)動 struct driver {char name[20]; // 驅(qū)動名稱int id; // 驅(qū)動id編號struct driver_info info; // 驅(qū)動信息struct list_head head; // 內(nèi)嵌的內(nèi)核鏈表成員 };struct driver2 {char name[20]; // 驅(qū)動名稱int id; // 驅(qū)動id編號struct driver_info info; // 驅(qū)動信息//struct list_head head; // 內(nèi)嵌的內(nèi)核鏈表成員struct driver *prev;struct driver *next; };// 分析driver結(jié)構(gòu)體,可知:前三個成員都是數(shù)據(jù)區(qū)域成員(就是我們之前簡化為int data的東西),第4個成員是一個struct list_head類型的變量,這就是一個純鏈表。 // 本來driver結(jié)構(gòu)體是沒有鏈表的,也無法用鏈表來管理。但是我們driver內(nèi)嵌的head成員本身就是一個純鏈表,所以driver通過head成員給自己擴展了鏈表的功能。 // driver通過內(nèi)嵌的方式擴展鏈表成員,本身不只是有了一個鏈表成員,關(guān)鍵是可以通過利用list_head本身事先實現(xiàn)的鏈表的各種操作方法來操作head。// 最終效果:我們可以通過遍歷head來實現(xiàn)driver的遍歷;遍歷head的函數(shù)在list.h中已經(jīng)事先寫好了,所以我們內(nèi)核中去遍歷driver時就不用重復(fù)去寫了。 // 通過操作head來操作driver,實質(zhì)上就是通過操作結(jié)構(gòu)體的某個成員變量來操作整個結(jié)構(gòu)體變量。這里面要借助container_of宏
總結(jié)
- 上一篇: php copy array,ES6中A
- 下一篇: 攻击者利用7号信令(SS7)中的漏洞从德