鴻蒙內(nèi)核源碼分析(雙向鏈表篇) | 最重要結(jié)構(gòu)體
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
https://harmonyos.51cto.com/#zz
鴻蒙內(nèi)核源碼注釋中文版 < Gitee倉 | CSDN倉 | Github倉 | Coding倉 >精讀內(nèi)核源碼,中文注解分析,深挖地基工程,構(gòu)建底層網(wǎng)圖,四大碼倉每日同步更新。
鴻蒙源碼分析系列篇 < CSDN | OSCHINA | WeHarmony | 公眾號 >問答式導(dǎo)讀,生活式比喻,表格化說明,圖形化展示,主流站點每日同步更新。
誰是鴻蒙內(nèi)核最重要的結(jié)構(gòu)體?
答案一定是: LOS_DL_LIST(雙向鏈表),它長這樣。
- typedef struct LOS_DL_LIST {//雙向鏈表,內(nèi)核最重要結(jié)構(gòu)體
- struct LOS_DL_LIST *pstPrev; /**< Current node's pointer to the previous node *///前驅(qū)節(jié)點(左手)
- struct LOS_DL_LIST *pstNext; /**< Current node's pointer to the next node *///后繼節(jié)點(右手)
- } LOS_DL_LIST;
結(jié)構(gòu)體夠簡單了吧,只有前后兩個指向自己的指針,但恰恰是因為太簡單,所以才太不簡單. 就像氫原子一樣,宇宙中無處不在,占比最高,原因是因為它最簡單,最穩(wěn)定!
內(nèi)核的各自模塊都能看到雙向鏈表的身影,下圖是各處初始化雙向鏈表的操作,因為太多了,只截取了部分:

很多人問圖怎么來的, source insight 4.0 是閱讀大型C/C++工程的必備工具,要用4.0否則中文有亂碼。
可以豪不夸張的說理解LOS_DL_LIST及相關(guān)函數(shù)是讀懂鴻蒙內(nèi)核的關(guān)鍵。前后指針(注者后續(xù)將比喻成一對左右觸手)靈活的指揮著系統(tǒng)精準(zhǔn)的運行,越是深入分析內(nèi)核源碼,越能感受到內(nèi)核開發(fā)者對LOS_DL_LIST非凡的駕馭能力,筆者仿佛看到了無數(shù)雙手前后相連,拉起了一個個雙向循環(huán)鏈表,把指針的高效能運用到了極致,這也許就是編程的藝術(shù)吧!這么重要的結(jié)構(gòu)體還是需詳細(xì)講解一下。
基本概念
雙向鏈表是指含有往前和往后兩個方向的鏈表,即每個結(jié)點中除存放下一個節(jié)點指針外,還增加一個指向其前一個節(jié)點的指針。其頭指針head是唯一確定的。從雙向鏈表中的任意一個結(jié)點開始,都可以很方便地訪問它的前驅(qū)結(jié)點和后繼結(jié)點,這種數(shù)據(jù)結(jié)構(gòu)形式使得雙向鏈表在查找時更加方便,特別是大量數(shù)據(jù)的遍歷。由于雙向鏈表具有對稱性,能方便地完成各種插入、刪除等操作,但需要注意前后方向的操作。
功能接口
鴻蒙系統(tǒng)中的雙向鏈表模塊為用戶提供下面幾個接口。
請結(jié)合下面的代碼和圖去理解雙向鏈表,不管花多少時間,一定要理解它的插入/刪除動作, 否則后續(xù)內(nèi)容將無從談起.
- //將指定節(jié)點初始化為雙向鏈表節(jié)點
- LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
- {
- list->pstNext = list;
- list->pstPrev = list;
- }
- //將指定節(jié)點掛到雙向鏈表頭部
- LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListAdd(LOS_DL_LIST *list, LOS_DL_LIST *node)
- {
- node->pstNext = list->pstNext;
- node->pstPrev = list;
- list->pstNext->pstPrev = node;
- list->pstNext = node;
- }
- //將指定節(jié)點從鏈表中刪除,自己把自己摘掉
- LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
- {
- node->pstNext->pstPrev = node->pstPrev;
- node->pstPrev->pstNext = node->pstNext;
- node->pstNext = NULL;
- node->pstPrev = NULL;
- }
具體用法
舉例 ProcessCB(進程控制塊)是描述一個進程的所有信息,其中用到了 8個雙向鏈表,這簡直比章魚還牛逼,章魚也才四雙觸手,但進程有8雙(16只)觸手。
- typedef struct ProcessCB {
- LOS_DL_LIST pendList; /**< Block list to which the process belongs */ //進程所屬的阻塞列表,如果因拿鎖失敗,就由此節(jié)點掛到等鎖鏈表上
- LOS_DL_LIST childrenList; /**< my children process list */ //孩子進程都掛到這里,形成雙循環(huán)鏈表
- LOS_DL_LIST exitChildList; /**< my exit children process list */ //那些要退出孩子進程掛到這里,白發(fā)人送黑發(fā)人。
- LOS_DL_LIST siblingList; /**< linkage in my parent's children list */ //兄弟進程鏈表, 56個民族是一家,來自同一個父進程.
- ProcessGroup *group; /**< Process group to which a process belongs */ //所屬進程組
- LOS_DL_LIST subordinateGroupList; /**< linkage in my group list */ //進程是組長時,有哪些組員進程
- UINT32 threadGroupID; /**< Which thread group , is the main thread ID of the process */ //哪個線程組是進程的主線程ID
- UINT32 threadScheduleMap; /**< The scheduling bitmap table for the thread group of the
- process */ //進程的各線程調(diào)度位圖
- LOS_DL_LIST threadSiblingList; /**< List of threads under this process *///進程的線程(任務(wù))列表
- LOS_DL_LIST threadPriQueueList[OS_PRIORITY_QUEUE_NUM]; /**< The process's thread group schedules the
- priority hash table */ //進程的線程組調(diào)度優(yōu)先級哈希表
- volatile UINT32 threadNumber; /**< Number of threads alive under this process */ //此進程下的活動線程數(shù)
- UINT32 threadCount; /**< Total number of threads created under this process */ //在此進程下創(chuàng)建的線程總數(shù)
- LOS_DL_LIST waitList; /**< The process holds the waitLits to support wait/waitpid *///進程持有等待鏈表以支持wait/waitpid
- } LosProcessCB;
看個簡單點的 pendList表示這個進程中所有被阻塞的任務(wù)(task)都會掛到這個鏈表上管理. 任務(wù)阻塞的原因很多,可能是申請互斥鎖失敗,可能等待事件讀消息隊列,還可能開了一個定時任務(wù)等等。
再來看一個復(fù)雜點的 threadPriQueueList,這又是干嘛的?從名字可以看出來是線程的隊列鏈表,在鴻蒙內(nèi)核線程就是任務(wù)(task),任務(wù)分等了32個優(yōu)先級,同級的任務(wù)放在同一個雙向鏈表中, 32級就是32個雙向鏈表,所以是個鏈表數(shù)組,每條鏈表中存放的是已就緒等待被調(diào)度的任務(wù)。
雙向鏈表是內(nèi)核最重要的結(jié)構(gòu)體,精讀內(nèi)核的路上它會反復(fù)的映入你的眼簾,理解它是理解內(nèi)存運作的關(guān)鍵所在!
作者郵箱:weharmony@126.com
鴻蒙內(nèi)核源碼注釋中文版 < Gitee倉 | CSDN倉 | Github倉 | Coding倉 >精讀內(nèi)核源碼,中文注解分析,深挖地基工程,構(gòu)建底層網(wǎng)圖,四大碼倉每日同步更新
鴻蒙源碼分析系列篇 < CSDN | OSCHINA | WeHarmony | 公眾號 >問答式導(dǎo)讀,生活式比喻,表格化說明,圖形化展示,主流站點每日同步更新
©著作權(quán)歸作者和HarmonyOS技術(shù)社區(qū)共同所有,如需轉(zhuǎn)載,請注明出處,否則將追究法律責(zé)任。
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
https://harmonyos.51cto.com/#zz