码迷,mamicode.com
首页 > 其他好文 > 详细

内核链表的应用

时间:2014-07-14 14:44:29      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   使用   os   数据   

本文构建了一个双向循环的内核链表,然后对链表进行遍历并打印了数据,最后释放了链表节点。使用到的数据结构和链表操作函数如下:

             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节点是不用单独去释放的,该结构体一般会以结构体变量的形式保存在更大的结构体中,只要释放更大结构题即可。如本例所示的那样。

 

内核链表的应用,布布扣,bubuko.com

内核链表的应用

标签:style   blog   color   使用   os   数据   

原文地址:http://www.cnblogs.com/liangning/p/3841768.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!