内核链表是Linux 内核中最常用的数据结构,代码位于 内核/include/linux/list.h 下 ,此代码是可以在应用程序进行编译直接使用的,因此当我们想要设计链表时可以直接使用此代码。
定义一个链表头
struct list_head *list;
初始化链表头
INIT_LIST_HEAD(list)//list为链表头
正向插入链表节点
list_add(&new_list,list)//new_list 待插入的链表节点, list 链表头
反向插入链表节点
list_add_tail(&new_list,list)//new_list 待插入的链表节点, list 链表头在这里插入代码片
遍历链表节点
list_for_each_entry(pos,head,member)
//pos为待遍历的数据结构
//head为链表头
//member为链表节点下的list
链表节点删除
list_del(list) //直接删除链表节点
list_del_init(list)//删除链表节点后并初始化
判断链表是否为空`
list_empty(list)//为空返回true 否则返回false
这里给出一个demo ,此demo包含对内核线程的测试
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/kmod.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/kthread.h>
//typedef static STA;
//typedef char bool;
struct task_struct *task=NULL; //内核线程
int cnt=0;
//student_t为待插入链表的节点
typedef struct student{
int age;
char name[20];
char sex;
struct list_head list;//如果需要插入链表则需要链表结构
}student_t;
typedef struct {
struct list_head lStu; //链表头
}class_t;
void fun1(void)
{
printk("fun1\n");
}
void fun2(void)
{
printk("fun2\n");
}
int task_thread(void *arg) //内核线程函数
{
while(!kthread_should_stop()){ //内核线程停止
cnt++;
printk("start thread\n");
set_current_state(TASK_UNINTERRUPTIBLE); //睡眠
printk("schedule\n");
fun1();
if(cnt == 2)
{
printk("time out\n");
schedule_timeout(20*HZ); //20s后调度此线程
}else
{
printk("no time out\n");
schedule(); //直接调度
}
printk("end schedule cnt = %d\n",cnt);
fun2();
}
return 0;
}
static int mylist_init(void)
{
printk("my list init\n");
class_t class;
int i=0;
INIT_LIST_HEAD(&class.lStu);
student_t *stu;
student_t *pRemain;
stu = kmalloc(sizeof(student_t )*5,GFP_KERNEL);
if(!stu)
printk("malloc failed\n");
for(i=0;i<3;i++)
{
(stu+i)->age=100+i+2;
(stu+i)->sex=i;
sprintf((stu+i)->name,"stu %d",i);
INIT_LIST_HEAD(&(stu+i)->list); //初始化链表
}
for(i=0;i<3;i++)
{
list_add_tail(&(stu+i)->list,&class.lStu);//节点插入
}
stu->age=101;
sprintf(stu->name,"first");
list_for_each_entry(pRemain,&class.lStu,list)
{
printk("pRemain->name:%s\n",pRemain->name);
}
pRemain = list_entry(class.lStu.next,student_t,list);
printk("pRemain->name:%s\n",pRemain->name);
task = kthread_run(task_thread,NULL,"test_task");//创建并运行内核线程
return 0;
}
static void mylist_exit(void)
{
printk("my list exit\n");
kthread_stop(task);
}
module_init(mylist_init);
module_exit(mylist_exit);
MODULE_LICENSE("GPL");