Linux内核链表的移植与使用
生活随笔
收集整理的這篇文章主要介紹了
Linux内核链表的移植与使用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、Linux內核鏈表為雙向循環鏈表,和數據結構中所學鏈表類似,具體不再細講。由于在內核中所實現的函數十分經典,所以移植出來方便后期應用程序中的使用。
/**************************************** 文件名:kernel_link_list_of_linux.h 作者:Bumble Bee 日期:2015-1-31 功能:移植linux內核鏈表 *****************************************//*鏈表結點數據結構*/ struct list__head {struct list_head *next, *prev; };/**************************************** 函數名: INIT_LIST_HEAD 參數: 指向list_head結構體的指針 返回值: 無 函數功能:通過將前向指針和后向指針指向自己來創建一個鏈表表頭 *****************************************/ static inline void INIT_LIST_HEAD(struct list_head *list) {list->next = list;list->prev = list; }/*************************************** 函數名: __list_add 參數: @new:要插入結點的指針域@prev: 前一個節點的指針域@next: 后一個節點的指針域 返回值:無 函數功能:在兩個已知節點中插入新節點 ***************************************/ static inline void __list_add(struct list_head *new,struct list_head *prev, struct list_head *next) {next->prev = new;new->next = next;new->prev = prev;prev->next = new; } extern void __list_add(struct list_head *new,struct list_head *prev, struct list_head *next);/************************************** 函數名: list_add 參數: @new: 要插入結點的指針域@head: 要插入鏈表表頭的指針域 返回值: 無 函數功能: 在已知鏈表頭部插入新節點 **************************************/ static inline void list_add(struct list_head *new, struct list_head *head) {__list_add(new, head, head->next); }/************************************* 函數名: list_add_tail 參數: @new: 要插入結點的指針域@head: 要插入鏈表表頭的指針域 返回值:無 函數功能: 在已知鏈表尾部插入新結點 **************************************/ static inline void list_add_tail(struct list_head *new, struct list_head *head) {__list_add(new, head->prev, head); }/************************************* 函數名: list_for_each 參數: @pos: 遍歷鏈表的光標@head: 要遍歷鏈表的表頭 返回值:無 函數功能:實際為一個for循環,遍歷鏈表 **************************************/ #define list_for_each(pos, head) \for (pos = (head)->next; pos != (head); \pos = pos->next;/************************************* 函數名: list_entry 參數: @ptr: 節點中list_head的地址@type: 節點的類型@member: list_head 在結構體中成員的名字 返回值:節點的地址,已被強制轉化為type型指針 函數功能: 將節點最低位置假設為0,此時取成員member的地址即為offset,再用list_head的地址將offset減去即為節點的地址 **************************************/ #define list_entry(ptr, type, member) \container_of(ptr, type, member)#define container_of(ptr, type, member) ({ \const typeof(((type *)0)->member) * __mptr = (ptr); \(type *)((char *)__mptr - offsetof(type, member)); })#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)static inline void __list_del(struct list_head *prev, struct list_head *next) {next->prev = prev;prev->next = next; }static inline void list_del(struct list_head *entry) {__list_del(entry->prev, entry->next); }二、設計應用程序測試鏈表
/********************************** 文件名: homework.c 作者: Bumble Bee 日期: 2015-1-31 功能:測試移植的linux內核鏈表 ***********************************/ #include <stdio.h> #include "kernel_link_list_of_linux.h"struct score {int num;int english;int math;struct list_head list; };struct score stu1, stu2, stu3, *temp;struct list_head score_head, *pos;int main() {INIT_LIST_HEAD(&score_head); //創建鏈表函數stu1.num = 1;stu1.english = 0;stu1.math = 0;list_add_tail(&(stu1.list), &(score_head));stu2.num = 2;stu2.english = 1;stu2.math = 1;list_add_tail(&(stu2.list), &(score__head));stu3.num = 3;stu3.english = 2;stu3.math = 2;list_add_tail(&(stu3.list), &(score_head));list_del(&(stu2.list));list_for_each(pos, &(score_head)){temp = list_entry(pos, struct score, list);printf("No %d, english is %d, math is %d\n", temp->num, temp->english, temp->math);}return 0; }三、運行結果
轉自:https://www.cnblogs.com/51qianrushi/p/4294406.html
總結
以上是生活随笔為你收集整理的Linux内核链表的移植与使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用top命令监控linux系统cpu变
- 下一篇: C/C++ strlen函数为什么不能传