Linux 内核链表使用举例
链表数据结构的定义非常简洁:
struct list_head {
struct list_head *next, *prev;
};
list_head结构包括两个指向list_head结构的指针prev和next。该内核链表具备双链表功能。通常它都组织成双循环链表,这里的list_head没有数据域。在Linux内核链表中,不是在链表结构中包括数据,而是在数据结构中包括链表节点。以下是一个简单的内核模块的样例。包括了对链表进行插入、删除、遍历的一些函数:
list.c:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/list.h> typedef struct list_test_struct {
int num;
struct list_head list;
}test; struct list_head head_list;
rwlock_t list_lock = RW_LOCK_UNLOCKED; //定义读写锁,操作前加锁,操作后解锁 void creat_list(void)
{
test *s = NULL;
int i = 0;
for (i = 0; i < 10; i++)
{
s = (test *)kmalloc(sizeof(test), GFP_ATOMIC);
if (!s) return ;
s->num = i;
write_lock(&list_lock);
list_add_tail(&(s->list), &head_list); //加入节点
write_unlock(&list_lock);
}
} void del_data(void)
{
test *s;
struct list_head *p; write_lock(&list_lock);
list_for_each(p, &head_list) //遍历链表
{
s = list_entry(p, test, list);
if (s->num == 4)
{
list_del(p); //删除节点
write_unlock(&list_lock);
return ;
}
}
write_unlock(&list_lock);
} void print_list(void)
{
test *s;
struct list_head *p;
read_lock(&list_lock);
list_for_each(p, &head_list)
{
s = list_entry(p, test, list);
printk(KERN_INFO"%d\n", s->num);
}
read_unlock(&list_lock);
} int list_test_init(void)
{
INIT_LIST_HEAD(&head_list);
creat_list();
print_list();
del_data();
print_list();
return 0;
} void list_test_exit(void)
{
return;
} MODULE_LICENSE("GPL");
module_init(list_test_init);
module_exit(list_test_exit);
Makefile:
obj-m += list.o KERN_DIR = /usr/src/linux-headers-2.6.32-33-generic all:
make -C $(KERN_DIR) M=`pwd` modules clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
make后生成module,获取超级用户权限后
insmod list.ko
然后输入命令:
cat var/log/messages
printk信息打印:
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274551] 0
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274553] 1
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274555] 2
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274555] 3
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274556] 4
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274557] 5
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274558] 6
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274559] 7
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274559] 8
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274560] 9
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274561] 0
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274562] 1
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274563] 2
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274564] 3
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274564] 5
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274565] 6
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274566] 7
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274567] 8
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274568] 9
第二次输出发现节点4被删除。在这里实现:
list_for_each(p, &head_list) //遍历链表
{
s = list_entry(p, test, list);
if (s->num == 4)
{
list_del(p); //删除节点
write_unlock(&list_lock);
return ;
}
}
Linux 内核链表使用举例的更多相关文章
- linux内核链表分析
一.常用的链表和内核链表的区别 1.1 常规链表结构 通常链表数据结构至少应包含两个域:数据域和指针域,数据域用于存储数据,指针域用于建立与下一个节点的联系.按照指针域的组织以及各个节 ...
- C语言 Linux内核链表(企业级链表)
//Linux内核链表(企业级链表) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> ...
- 深入分析 Linux 内核链表--转
引用地址:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 一. 链表数据结构简介 链表是一种常用的组织有序数据 ...
- Linux 内核链表
一 . Linux内核链表 1 . 内核链表函数 1.INIT_LIST_HEAD:创建链表 2.list_add:在链表头插入节点 3.list_add_tail:在链表尾插入节点 4.list_d ...
- 深入分析 Linux 内核链表
转载:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/ 一. 链表数据结构简介 链表是一种常用的组织有序数据的数据结构,它通过指 ...
- Linux 内核 链表 的简单模拟(2)
接上一篇Linux 内核 链表 的简单模拟(1) 第五章:Linux内核链表的遍历 /** * list_for_each - iterate over a list * @pos: the & ...
- Linux 内核 链表 的简单模拟(1)
第零章:扯扯淡 出一个有意思的题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量,如 struct student { int a; //FIND(struct stu ...
- linux内核链表的移植与使用
一. Linux内核链表为双向循环链表,和数据结构中所学链表类似,具体不再细讲.由于在内核中所实现的函数十分经典,所以移植出来方便后期应用程序中的使用. /********************* ...
- [国嵌攻略][108][Linux内核链表]
链表简介 链表是一种常见的数据结构,它通过指针将一系列数据节点连接成一条数据链.相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入 ...
随机推荐
- WPF-MVVM-Demo
MVVM The model-view-viewmodel is a typically WPF pattern. It consists of a view that gets all the us ...
- angularjs $location 服务
<!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...
- [BZOJ1858] [SCOI2010] 序列操作 解题报告 (线段树)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1858 Description lxhgww最近收到了一个01序列,序列里面包含了n个数, ...
- 知方可补不足~powerDesign为模型添加注释(让生成的SQL有注释)
事实上powerDesign本身就有这个功能,不需要我们修改它的生成器了,这种方法够简单! 一 打开表模型,选择column标签
- C#篇(三)——函数传参之引用类型和值类型
首先应该认清楚在C#中只有两种类型: 1.引用类型(任何称为"类"的类型) 2.值类型(结构或枚举) 先来认识一下引用类型和值类型的区别: 函数传参之引用类型: 1.先来一个简单的 ...
- Python有了asyncio和aiohttp在爬虫这类型IO任务中多线程/多进程还有存在的必要吗?
最近正在学习Python中的异步编程,看了一些博客后做了一些小测验:对比asyncio+aiohttp的爬虫和asyncio+aiohttp+concurrent.futures(线程池/进程池)在效 ...
- AngularJS 导航栏动态添加.active
在传统jQuery中,实现导航栏动态添加.active类的思路比较简单,就是当点击的时候,清除其他.active,然后给当前类加上.active. 但是在AngularJS中,就不能再采用这种jQue ...
- Mojo Associated Interfaces
Mojo Associated Interfaces yzshen@chromium.org 02/22/2017 Background Before associated interfaces ar ...
- type与isinstance使用区别
Python中,type与isinstance都可以用来判断变量的类型,但是type具有一定的适用性,用它来判断变量并不总是能够获取到正确的值. Python在定义变量的时候不用指明具体的的类型,解释 ...
- cal---显示日历
cal命令用于显示当前日历,或者指定日期的日历. 语法 cal(选项)(参数) 选项 -l:显示单月输出: -3:显示临近三个月的日历: -s:将星期日作为月的第一天: -m:将星期一作为月的第一天: ...