[国嵌攻略][108][Linux内核链表]
链表简介
链表是一种常见的数据结构,它通过指针将一系列数据节点连接成一条数据链。相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入或删除数据。链表的开销主要是访问的顺序性和组织链的空间损失。
传统链表与Linux内核链表的区别
Linux内核链表是双向循环链表,提供一套统一的链表和操作函数。内核链表的节点由数据和指针两部分组成,不同的是指针不指向下一个节点的数据部分,而是指向下一个节点的指针部分。
内核链表的结构
struct list_head{
struct list_head *next, *prev;
};
list_head结构包含两个指向list_head结构的指针prev和next,由此可见,内核的链表具备双向链表功能,实际上通常它都组织成双向循环链表。
内核链表的函数
头文件<linux/list.h>
INIT_LIST_HEAD:创建链表
list_add:在链表头插入节点
list_ad_tail:在链表尾插入节点
list_del:删除节点
list_entry:取出节点
list_for_each:遍历链表
list_entry(ptr, type, member)
ptr:链表结点指针
type:链表结点
member:链表结点的指针名
实现方法是通过链表结点(type)减去链表结点的指针名(member)算出结点头部距离结点指针的偏移,然后让链表结点指针(ptr)指针指向链表结点头部。
list.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/list.h> //类型定义
typedef struct student{
int numb; //学生学号
int engl; //英语成绩
int math; //数学成绩
struct list_head node; //链表结点
}STUDENT; //加载函数
static int list_init(){
//创建链表
struct list_head student_head; INIT_LIST_HEAD(&student_head); //添加结点
STUDENT stu1, stu2, stu3; stu1.numb = ;
stu1.engl = ;
stu1.math = ;
list_add_tail(&(stu1.node), &student_head); stu2.numb = ;
stu2.engl = ;
stu2.math = ;
list_add_tail(&(stu2.node), &student_head); stu3.numb = ;
stu3.engl = ;
stu3.math = ;
list_add_tail(&(stu3.node), &student_head); //遍历结点
struct list_head *pos;
STUDENT *temp; list_for_each(pos, &student_head){
temp = list_entry(pos, STUDENT, node);
printk("No.%d, English is %d, Math is %d\n", temp->numb, temp->engl, temp->math);
} //删除结点
list_del(&(stu1.node));
list_del(&(stu2.node));
list_del(&(stu3.node)); return ;
} //卸载函数
static void list_exit(){ } //模块信息声明
MODULE_LICENSE("GPL");
MODULE_AUTHOR("D");
MODULE_DESCRIPTION("list");
MODULE_VERSION("v1.0"); //模块函数声明
module_init(list_init);
module_exit(list_exit);
Makefile
obj-m := list.o
KDIR := /space/work/guoqian/liunxkernel//kernel/linux-mini2440 all :
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux- clean :
@rm -f *.o *.ko *.mod.* *.order *.symvers
内核链表代码不涉及到任何内核调用,可以直接移植到应用程序中使用。
[国嵌攻略][108][Linux内核链表]的更多相关文章
- [国嵌攻略][098][Linux内核简介]
Linux系统架构 1.用户空间:应用程序.C函数库 2.内核空间:系统调用接口.内核.体系结构相关代码 Linux系统利用处理器不同的工作模式,使用其中的两个级别分别来运行Linux内核与应用程序, ...
- [国嵌攻略][099][Linux内核配置与编译]
为什么要配置内核 基于硬件和软件的需求选出需要的功能,去掉不要的功能. 内核配置的方法 make config:基于文本交互的配置. make menuconfig:基于图形菜单的配置. make m ...
- [国嵌攻略][107][Linux进程管理子系统]
进程与程序 1.程序:存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体. 2.进程:是一个执行中的程序,它是一个动态的实体. 进程四要素 1.有一段程序供其执行.这段程序不一定是某个进程所 ...
- [国嵌攻略][103][Linux内核模块基础]
什么是内核模块 Linux内核的整体结构非常庞大,其中包含的组件也非常多,如何使用这些组件.一种方式是把所有的组件都编译进内核文件,即zImage或bzImage,但这样会导致一个问题,占用内存过多. ...
- [国嵌攻略][119][Linux中断处理程序设计]
裸机中断: 1.中断统一入口. 2.注册中断处理程序. 3.根据中断源编号,调用中断处理程序. Linux中断 1.在entry-armv.S中的_irq_svc是中断统一入口. 2.获取产生中断源的 ...
- [国嵌攻略][106][Linux内存管理子系统]
内存管理子系统 1.虚拟地址与物理地址的映射 2.物理内存的分配 Linux虚拟地址空间分布 设备最后访问的一定是物理地址,但Linux系统中使用的都是虚拟地址.虚拟地址简单的来说就是程序中使用的地址 ...
- [国嵌攻略][104][Linux内核模块设计]
内核模块示例 #inlcude <linux/init.h> #inlcude <linux/module.h> static int hello_init(){ printk ...
- [国嵌攻略][070-095][Linux编程函数手册]
第1类 时间编程类 1.1 获取日历时间 1.1.1 函数名 time 1.1.2 函数原形 time_t time(time_t *t) 1.1.3 函数功能 返回日历时间 1.1.4 所属头文件 ...
- [国嵌攻略][109][Linux系统调用]
系统调用 函数实现体在内核空间,提供给应用程序来使用,就是一个系统调用. 工作流程 1.通过软中断(swi)从用户空间切换到内核空间.entry-common.S中的ENTRY(vector_swi) ...
随机推荐
- Docker 安装入门 --基础镜像
安装Docker1.Docker命令安装 yum install docker //安装docker包 service docker start //设置服务启动 chkconfig docker ...
- 防盗链与token运用
为什么要防盗链? 例如手机/PC应用,如果有人知道你的api地址,和应用格式,那么他人就可以利用这个接口进行盗链:盗取/盗用里面的数据. 防盗链特性: 1.因为是非开放性的,所以所有的接口都是封闭的, ...
- 发短信utils
package cn.itcast.bos.utils; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; ...
- Sticky Footer 绝对底部的两种套路
最近面了好几个前端,工作经验有高有低,居然都不知道绝对底部是什么,也没有人能说出一种实现方式,让我不禁感慨前端领域的良莠不齐 绝对底部,或者说 Sticky Footer,是一种古老且经典的页面效果: ...
- JS中date日期初始化的5种方法
创建一个日期对象: 代码如下: var objDate=new Date([arguments list]); 参数形式有以下5种: 1)new Date("month dd,yyyy hh ...
- 线上服务器上安装的VNCServer不能正常工作
1.问题描述: 线上服务器上安装的不能正常工作 2.解决问题过程: 一. 重启vncserver 运行命令:vncserver -kill :1和vncserver :1 二. 发现vncserver ...
- Mac OSX下Sublime Text配置使用Ctags实现代码跳转
1. 先用brew工具安装ctags,安装路径在/user/local/bin The default ctags executable in OSX does not support recursi ...
- Python模块学习------ 多线程threading(2)
一.避免使用thread模块,使用threading模块的原因: 1. 更高级别的threading模块更为先进,对线程的支持更加完善.而且使用thread模块的属性有可能会与threading 出现 ...
- django之admin流程
admin 类复习: class Base(object): def __init__(self,val): self.val = val def func(self): self.test() pr ...
- windows平台调用函数堆栈的追踪方法
在windows平台,有一个简单的方法来追踪调用函数的堆栈,就是利用函数CaptureStackBackTrace,但是这个函数不能得到具体调用函数的名称,只能得到地址,当然我们可以通过反汇编的方式通 ...