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内核链表,实现栈这样的数据结构. 要实现的 ...
随机推荐
- 企业QQ客服的添加
商城项目需要用腾讯的企业QQ客服,但默认提供的是一个链接,点击后弹出一个新页面, 请确认 确认打开QQ与营销QQ4009928310对话? 点确认才弹出聊天窗口,并不是需求想要的效果,经过一番折腾联系 ...
- Iterator、for..of,for...in和自定义遍历器**
Iterator.for..of,for...in和自定义遍历器 Iterator: var arr = [1,2,3,4,5]; var ite = arr[Symbol.iterator](); ...
- docker~通过vs2017的Dockerfile来生成镜像
回到目录 Dockerfile这个东西我们之前是介绍过,它方便,快捷,易用,而在vs2017中也对docker进行了支持,而生成docker image的方式就是有用Dockerfile为基础的,在添 ...
- Java创建连接池连接不同数据库
在一个应用里面,可能涉及到连接多个不同数据库进行操作,而每次连接写不同的实现会很麻烦.前面已经会了用JDBC连接数据库,那么利用反射和工厂模式,可以实现连接不同的数据库,这样处理起来将会很方便.同时建 ...
- hdu_4717: The Moving Points 【三分】
题目链接 第一次写三分 三分的基本模板 int SanFen(int l,int r) //找凸点 { ) { //mid为中点,midmid为四等分点 ; ; if( f(mid) > f(m ...
- android - 解决“应用自定义权限重名”
背景 现场的开发今天跟我说,测试包装不上!报错"应用自定义权限重名"!!! 网上百度下关键字,发现魅族手机有这个毛病,顺藤摸瓜:"http://bbs.flyme.cn/ ...
- 【samba】samba 用户权限配置(转)
首先要保证你的samba安装并配置好,关于安装和配置samba请参考此文章 http://blog.csdn.net/linglongwunv/archive/2010/01/19/5212875.a ...
- pwnable.kr col之write up
Daddy told me about cool MD5 hash collision today. I wanna do something like that too! ssh col@pwnab ...
- Unity3D 中材质球(Material)预制体打包成AB(AssetBundle)出现材质丢失问题的解决方案
关于Unity3D中打AB(AssetBundle)资源包,默认是不连Shader一同打包进去的,所以得自行添加,添加方式比较简单,不需要往项目中添加Shader,只是点选一下就可以了,具体实现方式如 ...
- MapReduce框架Hadoop应用(一)
Google对其的定义:MapReduce是一种变成模型,用于大规模数据集(以T为级别的数据)的并行运算.用户定义一个map函数来处理一批Key-Value对以生成另一批中间的Key-Value对,再 ...