Linux中的内核链表
链表中一般都要进行初始化、插入、删除、显示、释放链表,寻找节点这几个操作,下面我对这几个操作进行简单的介绍,因为我的能力不足,可能有些东西理解的不够深入,造成一定的错误,请各位博友指出。
A、Linux内核链表中的几个主要函数(下面是内核中的源码拿出来给大家分析一下)
1)初始化:
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0) // ptr为struct list_head,其中包括两个指针next和prev,这里已经可以看出内核链表是双向循环链表
2)尾部插入:
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
} //尾部插入,传入的参数是新节点中的两个指针和头结点中的两个指针
3)头部插入函数
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
} //头插入函数,传入的参数是新节点中的两个指针和头结点中的两个指针
4)删除节点函数
static inline void list_del(struct list_head *entry) //传入要删除节点中的指针域
{
__list_del(entry->prev, entry->next);//两个参数分别为所删除节点前一个节点和后一个节点
entry->next = (void *) 0;//删除节点后置为空
entry->prev = (void *) 0;
}
5)显示函数(如果要打印出链表中的信息的话要自己写成打印的函数,比如printf,因为这个其实是一个遍历的函数,没有显示的功能)
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/* 这个函数用于遍历链表
pos为节点指针,
head是头结点中的两个指针的地址
member为各节点中的指针域
*/
6)删除链表
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
//这里面的pos和n都是list_head指针,n指针是用于在删除时不让链表断链
7)寻找节点(这也是用的内核中的遍历函数)
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
B.下面来段代码给大家看看具体的运用方法
#include"kernel.h" //这是内核链表的头文件,一定要包含
#include<errno.h>
#include<stdio.h>
#include<stdlib.h> typedef struct list_node
{
int data;
struct list_head list;//节点的指针域是被封装在struct list_head这个结构体内
//这个结构体中包括struct list_head *next,*prev
}*node,node1; node init_head(node head)//初始化空链表
{
head = (node)malloc(sizeof(node1));//为节点分配空间
if(head == NULL)
{
perror("head");
return NULL;
}
INIT_LIST_HEAD(&(head->list));//#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while ()//调用内核中的初始化函数,传入的参数是
//节点的中两个指针,即struct list_head结构体中的两个指针
return head;
} node insert_tail(node head,int data)//尾部插入函数
{
node new = (node)malloc(sizeof(node1));//为新节点分配空间
if(new == NULL)//判断一下分配空间是否成功
{
perror("new:");
return NULL;
}
new->data = data;
list_add_tail(&(new->list),&(head->list));//调用内核中的从尾部插入的函数,传入的参数为新节点中的两个指针
//和头结点中的两个指针
return ;
} head_insert_node(node head,int data)//头插入函数
{
node new;//创建一个新节点
new = (node)malloc(sizeof(node1));//为新节点分配空间
if(new == NULL)//判断一下分配空间是否成功
{
perror("new:");
return ;
}
new->data = data;
list_add(&(new->list),&(head->list));//调用内核中从头插入的函数,传入的参数为新节点的两个指针和头结点的两个指针
return ;
} node search_node(node head,int data)//寻找节点函数
{
node p = NULL;
list_for_each_entry(p,&(head->list),list) //内核中的遍历函数
{
if(p->data == data) //p即为需要找的节点
{
printf("found the data:%d\n",p->data);
goto OK;
}
} puts("not found the data!");
return NULL; OK:
return p;
} int show_node(node tmp)
{
if(tmp == NULL)
{
puts("tmp is NULL!");
return -;
}
printf("the data is %d\n",tmp->data);
return ;
} int delete_node(node head,int data)
{
node p = NULL;
list_for_each_entry(p,&(head->list),list)
{
if(p->data == data)
{
printf("found the data which you want to delete!\n");
goto f;
}
} f:
list_del(&(p->list));
free(p);
return ;
} int show_list(node head)
{
node p = NULL;
list_for_each_entry(p,&(head->list),list)
{
printf("data:%d\n",p->data);
}
return ;
} int delete_list(node head)//删除链表函数
{
node p,q;
list_for_each_entry_safe(p,q,&(head->list),list)//这是内核中的安全删除函数
{
list_del(&(p->list));
free(p);
} list_del(&(head->list));
free(head);
return ;
}
int main(int argc,char **argv)
{
node head;
node tmp;
head = init_head(head);//初始化空链表函数
insert_tail(head,);//从末尾插入函数
insert_tail(head,);
insert_tail(head,); head_insert_node(head,);//从头插入函数
show_list(head); //显示链表函数 tmp = search_node(head,);//寻找结点函数
show_node(head);
delete_node(head,);
//show_list(head);
delete_list(head);//删除链表函数
return ;
}
Linux中的内核链表的更多相关文章
- Mysql : L闪存卡linux中的内核参数设置
将 Nytro WarpDrive 加速卡配置为文件系统 本节说明的操作使您可调整 Nytro WarpDrive 加速卡,增强使用 Oracle Linux with Unbreakable Ent ...
- linux中的内核级防火墙(SELINUX)
SElinux是基于内核开发出来的一种安全机制,被称之为内核级加强型防火墙,有力的提升了系统的安全性. SElinux的作用分为两方面:1.在服务上面加上标签: 2.在功能上面限制功能 在linux系 ...
- linux中文件内核数据结构
3.文件io 3.1 文件内核数据结构 3.2 复制文件描述符的内核数据结构 3.3 对指定的描述符打印文件标志 #include "apue.h" #include <fc ...
- 深入分析 Linux 内核链表--转
引用地址:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 一. 链表数据结构简介 链表是一种常用的组织有序数据 ...
- linux内核链表分析
一.常用的链表和内核链表的区别 1.1 常规链表结构 通常链表数据结构至少应包含两个域:数据域和指针域,数据域用于存储数据,指针域用于建立与下一个节点的联系.按照指针域的组织以及各个节 ...
- 深入分析 Linux 内核链表
转载:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/ 一. 链表数据结构简介 链表是一种常用的组织有序数据的数据结构,它通过指 ...
- Linux内核链表-通用链表的实现
最近编程总想着参考一些有名的开源代码是如何实现的,因为要写链表就看了下linux内核中对链表的实现. 链表是一种非常常见的数据结构,特别是在动态创建相应数据结构的情况下更是如此,然而在操作系统内核中, ...
- Linux 内核链表的使用及深入分析【转】
转自:http://blog.csdn.net/BoArmy/article/details/8652776 1.内核链表和普通链表的区别 内核链表是一个双向链表,但是与普通的双向链表又有所区别.内核 ...
- Linux内核链表复用实现栈
我们当然可以根据栈的特性,向实现链表一样实现栈.但是,如果能够复用已经经过实践证明的可靠数据结构来实现栈,不是可以更加高效吗? so,今天我们就复用Linux内核链表,实现栈这样的数据结构. 要实现的 ...
随机推荐
- 【JS小技巧】JavaScript 函数用作对象的隐藏问题
用户反馈 @消失的键盘 在论坛反馈了一个问题,在 AppBoxMvc 中的 Title 模型中,如果将 Name 属性改名为小写的 name 属性,就会报错: 因为这是一个 ASP.NET MVC 的 ...
- 与你们分享我学习linux系统的三大妙招
一说到linux,我们就自然会想到企业服务器系统,目前市场上的网络设备都是使用linux内核操作系统,一些网络服务器也是使用linux操作系统下面的服务搭建实现的:目前操作系统这块也基本被linux占 ...
- Java+Tomcat + Idea + Jrebel 实现热部署
1. 首先安装idea的jrebel插件, jrebel是收费的,所以要在网上下载验证码. 2. 安装好以后再setting 菜单能看到一个jrebel的菜单. 3. 4.其中需要选中frame失去 ...
- CSS命名实践
前面的话 每次写HTML结构涉及到CSS命名时,都要挣扎一番.关于CSS命名的规范,市面上有不少,如OOCSS.SMACSS.BEM和MVCSS等.在这里面最火的应该算BEM了.本文将详细介绍CSS命 ...
- JS实现悬浮导航的制作--web前端
思想:导航在这里只有两种状态,一种是初始状态.一种是固定布局状态.实现悬浮导航其实就是通过Javascript脚本语言控制导航的两种状态,主要是对两种状态成立条件的判断,明确了这些,实现起来就不会太难 ...
- Entity Framework Core 生成跟踪列
本文翻译自<Entity Framework Core: Generate tracking columns>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意:我使用的是 ...
- 还在为画“类Word文档报表”而发愁吗?
欢迎大家持续关注葡萄城控件技术团队博客,更多更好的原创文章尽在这里~~ Word 是非常强大的文档编辑工具,一些行业制式文档都是使用Word来创建的,像教育行业的申请表,履历表,审批表等,像石油业的 ...
- Linux服务器下对Oracle作Rman备份
由于工作需要,最近要对几台Linux系统下的Oracle数据库进行Rman备份,就在操作的同时,整理了一下,方便今后作为资料进行查阅. ------------------------Linux服务器 ...
- The first day,I get a blogs!!
我拥有了自己的博客,很happy! 今天学习了kvm,虽然命令行界面比较枯燥,还好不算太难,在大家的热心帮助下我创建了一个虚拟机!!
- Weak 和 Strong
介绍: ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编译 ...