linux内核链使用,linux内核链表的移植与使用

一、

Linux内核链表为双向循环链表,和数据结构中所学链表类似,具体不再细讲。由于在内核中所实现的函数十分经典,所以移植出来方便后期应用程序中的使用。

/***********************************

文件名:kernel link list of linux.h

作者:Bumble Bee

日期:2015-1-31

功能:移植linux内核链表

************************************/

/*链表结点数据结构*/

struct list_head

{

struct list_head *next, *prev;

};

/***********************************

函数名: INIT_LIST_HEAD

参数: 指向list_head结构体的指针

返回值: 无

函数功能:通过将前向指针和后向指

针指向自己来创建一个链表表

***********************************/

static inline void INIT_LIST_HEAD(struct list_head *list)

{

list->next = list;

list->prev = list;

}

/***********************************

函数名: __list_add

参数: @new:要插入结点的指针域

@prev:前一个节点的指针域

@next:后一个节点的指针域

返回值: 无

函数功能:在两个已知节点中插入新节点

***********************************/

static inline void __list_add(struct list_head *new,

struct list_head *prev, struct list_head *next)

{

next->prev = new;

new->next = next;

new->prev = prev;

prev->next = new;

}

extern void __list_add(struct list_head *new,

struct list_head *prev, struct list_head *next);

/**************************************

函数名: list_add

参数: @new:要插入结点的指针域

@head:要插入链表表头的指针域

返回值: 无

函数功能:在已知链表头部插入新节点

**************************************/

static inline void list_add(struct list_head *new, struct list_head *head)

{

__list_add(new, head, head->next);

}

/**************************************

函数名: list_add_tail

参数: @new:要插入结点的指针域

@head:要插入链表表头的指针域

返回值: 无

函数功能:在已知链表尾部插入新节点

**************************************/

static inline void list_add_tail(struct list_head *new, struct list_head *head)

{

__list_add(new, head->prev, head);

}

/*************************************

函数名: list_for_each

参数: @pos:遍历链表的光标

@head:要遍历链表的表头

返回值: 无

函数功能:实质为一个for循环,遍历链表

*************************************/

#define list_for_each(pos, head) \

for (pos = (head)->next;pos != (head); \

pos = pos->next)

/*************************************************

函数名: list_entry

参数: @ptr:节点中list_head的地址

@type:节点的类型

@member:list_head 在结构体中成员的名字

返回值: 节点的地址,已被强制转化为type型指针

函数功能:将节点最低位置假设为0,此时取成员member

的地址即为offset,再用list_head的地址将

offset减去即为节点的地址

**************************************************/

#define list_entry(ptr, type, member) \

container_of(ptr, type, member)

#define container_of(ptr, type, member) ({ \

const typeof(((type *))->member) * __mptr = (ptr); \

(type *)((char *)__mptr - offsetof(type, member)); })

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

static inline void __list_del(struct list_head *prev, struct list_head *next)

{

next->prev = prev;

prev->next = next;

}

static inline void list_del(struct list_head *entry)

{

__list_del(entry->prev, entry->next);

}

二、设计应用程序测试链表

/****************************

文件名:homework.c

作者:Bumble Bee

日期:2015-1-31

功能:测试移植的linux内核链表

*****************************/

#include

#include "kernel link list of linux.h"

struct score

{

int num;

int english;

int math;

struct list_head list;

};

struct score stu1,stu2,stu3,*temp;

struct list_head score_head,*pos;

int main()

{

INIT_LIST_HEAD(&score_head); //创建链表函数

stu1.num = ;

stu1.english = ;

stu1.math = ;

list_add_tail(&(stu1.list),&(score_head));

stu2.num = ;

stu2.english = ;

stu2.math = ;

list_add_tail(&(stu2.list),&(score_head));

stu3.num = ;

stu3.english = ;

stu3.math = ;

list_add_tail(&(stu3.list),&(score_head));

list_del(&(stu2.list));

list_for_each(pos,&(score_head))

{

temp = list_entry(pos,struct score,list);

printf("No %d,english is %d,math is %d\n",temp->num,temp->english,temp->math);

}

return ;

}

三、运行结果

4791ab773d0fc1168db7a816440e9c2d.png

[国嵌攻略][108][Linux内核链表]

链表简介 链表是一种常见的数据结构,它通过指针将一系列数据节点连接成一条数据链.相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入 ...

第32课 Linux内核链表剖析

1. Linux内核链表的位置及依赖 (1)位置:{linux-2.6.39}\\include\linux\list.h (2)依赖 ①#include ② ...

linux内核链表使用

原文链接:http://blog.csdn.net/xnwyd/article/details/7359373 Linux内核链表的核心思想是:在用户自定义的结构A中声明list_head类型的成员p ...

数据结构开发(10):Linux内核链表

0.目录 1.老生常谈的两个宏(Linux) 1.1 offsetof 1.2 container_of 2.Linux内核链表剖析 3.小结 1.老生常谈的两个宏(Linux) Linux 内核中常 ...

linux内核链表剖析

1.移植linux内核链表,使其适用于非GNU编译器 2.分析linux内核中链表的基本实现 移植时的注意事项 清除文件间的依赖 剥离依赖文件中与链表实现相关的代码 清除平台相关的代码(GNU C) ...

Linux内核链表——看这一篇文章就够了

本文从最基本的内核链表出发,引出初始化INIT_LIST_HEAD函数,然后介绍list_add,通过改变链表位置的问题引出list_for_each函数,然后为了获取容器结构地址,引出offseto ...

C语言 Linux内核链表(企业级链表)

//Linux内核链表(企业级链表) #define _CRT_SECURE_NO_WARNINGS #include #include ...

深入分析 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 ...

随机推荐

使用JDK开发WebService

一.WebService的开发手段 使用Java开发WebService时可以使用以下两种开发手段 1. 使用JDK开发(1.6及以上版本) 2.使用CXF框架开发(工作中) 二.使用JDK开发Web ...

Genymotion关于【启动后player.exe已停止运行】解决方案总结

1. 你硬盘空间不足,或是暂存区不够,请少执行一些程序或关掉一些p2p的程序,或是到控制面板卸载一些不必要的程序.最好的建议是定期进行硬盘清理,确保不浪费多余空间 ---以上来源(http://www ...

Git工作流指南:集中式工作流

转载:http://blog.jobbole.com/76847/ 本文由 伯乐在线 - 李鼎 翻译.未经许可,禁止转载!英文出处:atlassian.欢迎加入翻译组. 转到分布式版本控制系统看起来像 ...

(cljs/run-at (JSVM. :browser) "简单类型可不简单啊~")

前言  每逢学习一个新的语言时总要先了解这门语言支持的数据类型,因为数据类型决定这门语言所针对的问题域,像Bash那样内置只支持字符串的脚步明显就是用于文本处理啦.而数据类型又分为标量类型(Scala ...

[ Java学习基础 ] Java异常处理

一.异常概述 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的.比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error:如果你用Sys ...

Hibernate之实体关系映射

延迟加载与即时加载 例如Person类和Email类是一对多关系,如果设为即时加载,当加载Person时,会自动加载Email,如果设置为延迟加载,当第一次调用person.getEmails()时才 ...

SQL 如何在自增列插入指定数据

SQL Server  中数据表往往会设置自增列,常见的比如说 首列的ID列. 往数据表插入新数据的时候,自增列是跳过的,无需插入即会按照设置的自增规则进行列增长.那么,如果我们想往自增列插入我们指定 ...

Linux 下如何修改用户名(同时修改用户组名和家目录)

有时候,由于某些原因,我们可能会需要重命名用户名.我们可以很容易地修改用户名以及对应的家目录和 UID.-- Shusain 本文导航◈ 修改用户名12%◈ 修改家目录43%◈ 更改用户 UID52% ...

020-Json结构数据序列化异步传递

C#中将.Net对象序列化为Json字符串的方法: JavaScriptSerializer().Serialize(p),JavaScriptSerializer在System.Web.Extens ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值