Linux双向链表(五)——简单使用示例

原创 2013年12月03日 16:54:10

针对前面解析的双链表API,本文做一个简单使用实例。正所谓:千言万语,不如举一个好例子!不过,这个例子很简单,没有做安全机制,只是简单的使用,而且是链表的常用API,希望对读者能起到抛砖引玉的作用!

list_module.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>

static char *str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//定义一个用户数据类型
struct info_struct{
		char name[32];
		unsigned int age;

		struct list_head entry;
};

//双链表表头
static LIST_HEAD(head);

//遍历链表
static void print_list(void)
{
	struct info_struct *pos;
	struct list_head *list_head = &head;
	int i = 0;

	list_for_each_entry(pos, list_head, entry)
	{
		++i;
		printk(KERN_INFO"name:%s\tage:%d\n", pos->name, pos->age);
	}
	printk(KERN_INFO"sum:%d\n", i);
}

//销毁链表
static void destroy_list(void)
{
	struct info_struct *pos, *n;
	struct list_head *list_head = &head;

	list_for_each_entry_safe(pos, n, list_head, entry)
	{
		list_del(&pos->entry);
		kfree(pos);
	}
	INIT_LIST_HEAD(list_head);
}

static void creat_list(void)
{
	//向链表添加元素
	int i;
	struct info_struct *buff;

	for(i = 0; i < 10; ++i)
	{
		buff = kmalloc(sizeof(struct info_struct), GFP_ATOMIC);
		if(!buff)
		{
			printk(KERN_ALERT"ERROR:kmalloc memory fail!\n");
			break;
		}

		//初始化数据
		memcpy(buff->name, str + i, 17);
		buff->name[17] = 0;
		buff->age = 26 - i;

		//放入双链表
		list_add(&buff->entry, &head);
	}
}

//查找并删除元素
static void search_and_del_entry(unsigned int age)
{
	struct info_struct *pos, *n;
	
	list_for_each_entry_safe(pos, n, &head, entry)
	{
		if(pos->age == age)
		{
			list_del(&pos->entry);
			kfree(pos);
			printk(KERN_INFO"age:%d delete!\n", age);
		}
	}
}

//查找位置并插入之前
static void search_and_insert_entry(unsigned int age, struct info_struct *buff)
{
	struct info_struct *pos;
	
	list_for_each_entry(pos, &head, entry)
	{
		if(pos->age == age)
		{
			list_add_tail(&buff->entry, &pos->entry);
			printk(KERN_INFO"age:%d prev insert an entry!\n", age);
			break;
		}
	}
}

static int __init list_init(void)
{
	struct info_struct *buff;

	creat_list();
	print_list();

	search_and_del_entry(18);
	print_list();

	buff = kmalloc(sizeof(struct info_struct), GFP_ATOMIC);
	if(buff)
	{
		memcpy(buff->name, "Hello List, I'm newer!", 22);
		buff->name[22] = 0;
		buff->age = 0;
		search_and_insert_entry(24, buff);
		print_list();
	}
	printk(KERN_INFO"list_module insert successfully!\n");
	return 0;
}

static void __exit list_exit(void)
{
	destroy_list();
	printk(KERN_INFO"list_module remove successfully!\n");
}
module_init(list_init);
module_exit(list_exit);
MODULE_LICENSE("GPL");

Makefile

ifneq ($(KERNELRELEASE),)
	obj-m :=list_module.o
else
	KERNELDIR := /lib/modules/$(shell uname -r)/build
	PWD := $(shell pwd)
default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

步骤

make(编译模块)->insmod list_module.ko(root权限添加模块)->dmesg(查看运行结果)->rmmod list_module(root权限卸载模块)over!


相关文章推荐

和菜鸟一起学linux之双向链表list head的简单实例

经常在linux内核中看到list head这个链表头,有时候看着也不是很懂,很早就打算拎出来好好理解理解了。这次趁着编写SDK后有点小空闲,就拿出来晒晒吧。        简单的链表实现 #...

双向链表——1

  • 2014年05月02日 17:02
  • 524B
  • 下载

Linux双向链表(二)——逻辑判断

双链表判断函数 1、判断结点是不是链表head的最后一个结点 /** * list_is_last - tests whether @list is the last entry in list @...

Linux双向链表(四)——宏

通过前第一,二,三篇双向链表的博文,已经对双链表的基础操作函数做了文字与图片的说明。此博文将要展现操作链表的NB的宏,而且这些宏是最常用的操纵链表的接口,几乎是只要有双链表的地方,就有这些操作宏的使用...

Linux双向链表(一)——基础操作增、删、改

前言 数据结构中的链表在任何教程里面都是放在最前面讲解,这不仅仅体现它的重要性,而且说明了它的基础性。不说是地基,也能说是根葱,顶梁柱。而且在整个内核当中,无处不在。 记得在上大学的时候,学习数据结...

Linux双向链表(三)——基础操作拓展拆分与捻接

双向链表高级操作 在第一篇博文当中讨论的链表操作,是基础的增,删,改!而在本博文当中,将要在前文的基础操作上,封装高级的链表操作API,废话少说,开干!(+)_(+) 1、左向移动结点 static ...

双向链表模板类简单实现

  • 2013年12月12日 22:19
  • 1KB
  • 下载

(C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作

上午写了下单向循环链表的程序,今天下午我把双向链表的程序写完了。其实双向链表和单向链表也是有很多相似的地方的,听名字可以猜到,每个节点都包含两个指针,一个指针指向上一个节点,一个指针指向下一个节点。这...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux双向链表(五)——简单使用示例
举报原因:
原因补充:

(最多只允许输入30个字)