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