国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 操作系統 > 正文

內核鏈表的應用

2024-06-28 13:25:21
字體:
來源:轉載
供稿:網友
內核鏈表的應用

本文構建了一個雙向循環的內核鏈表,然后對鏈表進行遍歷并打印了數據,最后釋放了鏈表節點。

方法1:

使用到的數據結構和鏈表操作函數如下:

struct list_head    內核提供的雙向循環鏈表節點的結構體

LIST_HEAD(name)    該宏定義并初始化一個名為name的struct list_head類型節點

INIT_LIST_HEAD(name)    該宏初始化一個由name指向的 struct list_head類型節點,事先需要定義好一個struct list_head類型變量,

    并將變量的指針賦給name,然后再使用該宏

list_for_each(pos, head)    該宏可以遍歷以head為鏈表頭的循環鏈表,pos是遍歷到的每個節點,pos和head均為指針類型。

list_entry(ptr, type, number)   該宏可以得到type類型的結構體指針,number為包含在該type類型結構體中的struct list_head類型成員變量,

ptr為&number。返回值為指向type類型的指針。

list_for_each_safe(pos, n, head) 該宏類似于list_for_each宏,區別在于每次遍歷,n指向了pos的下一個節點。該宏可用于釋放鏈表節點之用。

程序代碼如下:

 1  #include <linux/slab.h> 2   #include <linux/sched.h> 3   #include <linux/module.h> 4   #include <linux/kernel.h> 5   #include <linux/init.h> 6   #include <linux/list.h> 7     8   struct fox { 9           int data;10           struct list_head list;11   };12   13   int i;14   struct list_head *temp;15   struct fox *tmp;16   LIST_HEAD(head);17   18   static int __init test_init(void)19   {20           for (i = 0; i < 10; i++) {21                   tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);22                   tmp->data = i;23                   INIT_LIST_HEAD(&tmp->list);24                   list_add_tail(&tmp->list, &head);25           }26   27           list_for_each(temp, &head) {28                   tmp = list_entry(temp, struct fox, list);29                   PRintk("<0> %d/n", tmp->data);30           }31   32           return 0;33   }34   35   static void __exit test_exit(void)36   {37           struct list_head *next;38   39           printk("<1> byebye/n");40           list_for_each_safe(temp, next, &head) {41                   tmp = list_entry(temp, struct fox, list);42                   printk("<0> %d/n", tmp->data);43                   kfree(tmp);44           }45   }46   47   module_init(test_init);48   module_exit(test_exit);49   MODULE_LICENSE("GPL");

需要注意的是,在釋放鏈表時,不可以直接用list_del(pos)宏來刪除節點,該宏僅僅是把struct list_head節點從其鏈表中卸下來,而且不釋放。而我們需要刪除的是fox結構體,所以只能使用本文中的這種方法,利用list_for_each_safe()宏,將需要釋放的節點指針保存到pos中,同時將下一個節點指針保存在next中,這樣就保證了釋放節點時鏈表不會丟失。其實list_head節點是不用單獨去釋放的,該結構體一般會以結構體變量的形式保存在更大的結構體中,只要釋放更大結構題即可。如本例所示的那樣。

方法2:

也可以用list_for_each_entry()和list_for_each_entry_safe()宏來完成,代碼如下:

 1 #include <linux/slab.h> 2 #include <linux/sched.h> 3 #include <linux/module.h> 4 #include <linux/kernel.h> 5 #include <linux/init.h> 6 #include <linux/list.h> 7  8 struct fox { 9     int data;10     struct list_head list;11 };12 13 int i;14 struct fox *tmp;15 LIST_HEAD(head);16 17 static int __init test_init(void)18 {19     for (i = 0; i < 10; i++) {20         tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);21         tmp->data = i;22         INIT_LIST_HEAD(&tmp->list);23         list_add_tail(&tmp->list, &head);24     }25 26     list_for_each_entry(tmp, &head, list) {27         printk("<0> %d/n", tmp->data);28     }29     30     return 0;31 }32 33 static void __exit test_exit(void)34 {35     struct fox *next;36 37     printk("<1> byebye/n");38     list_for_each_entry_safe(tmp, next, &head, list) {39         printk("<0> %d/n", tmp->data);40         kfree(tmp);    41     }42 }43 44 module_init(test_init);45 module_exit(test_exit);46 MODULE_LICENSE("GPL");

list_for_each_entry()是list_for_each()和list_entry()二者的結合體,在該程序中對二者進行了替換,使用起來更方便。

同樣,list_for_each_entry_safe是list_for_each_safe()和list_entry()二者的結合體,在本程序中替換了二者。其余都不變。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鹤峰县| 神池县| 久治县| 宁晋县| 云南省| 清河县| 山阴县| 北安市| 昭苏县| 济源市| 荃湾区| 紫云| 航空| 富平县| 中西区| 库车县| 攀枝花市| 循化| 阿瓦提县| 永春县| 通州区| 梧州市| 兴安盟| 霍城县| 牟定县| 新泰市| 阳东县| 临桂县| 苍梧县| 乐安县| 安阳县| 济宁市| 临西县| 甘肃省| 泸州市| 巨鹿县| 敦化市| 蓝山县| 江孜县| 汉源县| 寿光市|