内核链表使用

内核链表是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");

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值