您的位置:首页 > 健康 > 美食 > 引用计数器(kref)

引用计数器(kref)

2025/4/20 22:46:19 来源:https://blog.csdn.net/mantouyouyou/article/details/140333425  浏览:    关键词:引用计数器(kref)

1、什么是引用计数器

如果我们写了一个字符驱动,当硬件设备插上时,系统会生成一个设备节点。用户在应用空间操作这个设备节点就可以操作设备。如果此时将硬件断开,驱动是不是就要立刻释放呢?如果立刻释放,应用程序是不是就崩溃了呢。所以要等应用程序关闭,再去释放驱动。
在Linux系统中是通过引用计数来实现的。比如用kref这个变量记录某个驱动或者某块内存的引用计数。初始值为1,每引用一次+1,每取消一次-1,当计数值为0的时候,自动调用自定义的释放函数释放驱动或者内存。

2、相关结构体和api介绍

2.1 struct kref

在这里插入图片描述

2.2 kref_init

初始化kref的值为1
在这里插入图片描述

2.3 kref_get

计数值加1
在这里插入图片描述

2.4 kref_put

kref的计数值减1,当减到0时,会调用release函数执行释放的操作
在这里插入图片描述
在这里插入图片描述

3、kref实验

#include<linux/module.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/kobject.h>
#include<linux/slab.h>struct kobject *my_kobject01;
struct kobject *my_kobject02;
struct kobject *my_kobject03;struct kobj_type mytype;static int my_kobject_init(void)
{int ret;my_kobject01 = kobject_create_and_add("my_kobject01",NULL); // /sys/my_kobject01printk("my_kobject01 kref = %d\n",my_kobject01->kref.refcount.refs.counter);my_kobject02 = kobject_create_and_add("my_kobject02",my_kobject01); // /sys/my_kobject01/my_kobject02printk("my_kobject01 kref = %d\n",my_kobject01->kref.refcount.refs.counter);printk("my_kobject02 kref = %d\n",my_kobject02->kref.refcount.refs.counter);my_kobject03 = kzalloc(sizeof(struct kobject),GFP_KERNEL);ret = kobject_init_and_add(my_kobject03,&mytype,NULL,"%s","my_kobject03");printk("my_kobject03 kref = %d\n",my_kobject03->kref.refcount.refs.counter);return 0;
}static void my_kobject_exit(void)
{printk("my_kobject01 kref = %d\n",my_kobject01->kref.refcount.refs.counter);printk("my_kobject02 kref = %d\n",my_kobject02->kref.refcount.refs.counter);printk("my_kobject03 kref = %d\n",my_kobject03->kref.refcount.refs.counter);kobject_put(my_kobject01);printk("my_kobject01 kref = %d\n",my_kobject01->kref.refcount.refs.counter);printk("my_kobject02 kref = %d\n",my_kobject02->kref.refcount.refs.counter);printk("my_kobject03 kref = %d\n",my_kobject03->kref.refcount.refs.counter);kobject_put(my_kobject02);printk("my_kobject01 kref = %d\n",my_kobject01->kref.refcount.refs.counter);printk("my_kobject02 kref = %d\n",my_kobject02->kref.refcount.refs.counter);printk("my_kobject03 kref = %d\n",my_kobject03->kref.refcount.refs.counter);kobject_put(my_kobject03);printk("my_kobject01 kref = %d\n",my_kobject01->kref.refcount.refs.counter);printk("my_kobject02 kref = %d\n",my_kobject02->kref.refcount.refs.counter);printk("my_kobject03 kref = %d\n",my_kobject03->kref.refcount.refs.counter);}module_init(my_kobject_init);
module_exit(my_kobject_exit);
MODULE_LICENSE("GPL");
obj-m += kref.o
KDIR := /home/johan/share/rk3588/linux_sdk/kernel
PWD ?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modulesclean:rm -f *.ko *.o *mod* *.mod.c modules*  Module*

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com