[Linux内核驱动]自旋锁

自旋锁(spinlock)

更多内容可以查看我的github

概念

Spinlock是linux内核中常用的一种互斥锁机制,和mutex不同,当无法持锁进入临界区的时候,当前执行线索不会阻塞,而是不断的自旋等待该锁释放。 正因为如此,自旋锁也是可以用在中断上下文的。 也正是因为自旋,临界区的代码要求尽量的精简,否则在高竞争场景下会浪费宝贵的CPU资源。

使用

#include <linux/spinlock.h>
// 定义自选锁
spinlock_t lock;
// 初始化自旋锁
spin_lock_init(&lock);
// 获取自旋锁
spin_lock(&lock);
// 释放自旋锁
spin_unlock(&lock);

尽管使用自旋锁可以保证临界区不受别的CPU和本CPU内的抢占进程打扰。但是得到锁的代码路径在执行临界区的时候,可能受到 中断 的影响。因此,需要使用自旋锁的衍生函数。

// 锁 + 开/关中断
spin_lock_irq();
spin_unlock_irq();// 锁 + 关中断并保存中断状态/开中断并恢复中断状态
spin_lock_irqsave();
spin_unlock_irqrestore();

测试

make
dmesg -C
insmod spinlock.ko
mknod /dev/spinlock c 232 0cat /dev/spinlock
dmesg
echo "1" > /dev/spinlock
dmesg
cat /dev/spinlock
dmesg

代码

/** @Date: 2024-04-30 15:35:19* @author: lidonghang-02 2426971102@qq.com* @LastEditTime: 2024-05-19 20:02:50*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/device.h>#define DEVICE_NAME "spinlock_dev"#define SPINLOCK_MAJOR 0
static int spinlock_major = SPINLOCK_MAJOR;struct spinlock_dev
{struct cdev cdev;int shared_resource;struct device *class_dev;
};struct spinlock_dev *spinlock_devp;
struct class *my_class = NULL;
static dev_t dev_no;// 自旋锁
spinlock_t my_lock;static int spinlock_open_func(struct inode *inode, struct file *file)
{file->private_data = spinlock_devp;printk(KERN_INFO "Spinlock Device Opened\n");return 0;
}
static int spinlock_release_func(struct inode *inode, struct file *file)
{printk(KERN_INFO "Spinlock Device Closed\n");return 0;
}
static ssize_t spinlock_read_func(struct file *filp, char __user *buf, size_t size,loff_t *ppos)
{struct spinlock_dev *dev = filp->private_data;// 从用户空间读取数据if (copy_to_user(buf, &dev->shared_resource, sizeof(int))){printk(KERN_ERR "Failed to copy data to user space\n");return -EFAULT;}elseprintk(KERN_INFO "shared_resource: %d\n", dev->shared_resource);ppos += sizeof(int);return 0;
}
static ssize_t spinlock_write_func(struct file *filp, const char __user *buf, size_t size,loff_t *ppos)
{unsigned long flags;unsigned int count = size;struct spinlock_dev *dev = filp->private_data;// 加锁spin_lock_irqsave(&my_lock, flags);// 假设的共享资源操作dev->shared_resource += 1;// 解锁spin_unlock_irqrestore(&my_lock, flags);printk(KERN_INFO "shared_resource: %d\n", dev->shared_resource);return count;
}// 设备操作结构体
static const struct file_operations fops = {.open = spinlock_open_func,.release = spinlock_release_func,.read = spinlock_read_func,.write = spinlock_write_func,
};// 驱动初始化函数
static int __init my_driver_init_module(void)
{int ret;dev_no = MKDEV(spinlock_major, 0);spin_lock_init(&my_lock);// 分配设备号if (spinlock_major)ret = register_chrdev_region(dev_no, 1, DEVICE_NAME);else{ret = alloc_chrdev_region(&dev_no, 0, 1, DEVICE_NAME);spinlock_major = MAJOR(dev_no);}if (ret < 0){printk(KERN_ERR "Failed to allocate device number\n");return ret;}spinlock_devp = kzalloc(sizeof(struct spinlock_dev), GFP_KERNEL);if (!spinlock_devp){ret = -ENOMEM;goto free_chrdev_region;}my_class = class_create(THIS_MODULE, "spinlock");if (IS_ERR(my_class)){ret = PTR_ERR(my_class);goto free_chrdev_region;}// 初始化字符设备cdev_init(&spinlock_devp->cdev, &fops);spinlock_devp->cdev.owner = THIS_MODULE;ret = cdev_add(&spinlock_devp->cdev, dev_no, 1);if (ret < 0){printk(KERN_ERR "Failed to add cdev\n");goto free_chrdev_class;}spinlock_devp->class_dev = device_create(my_class, NULL, dev_no, NULL, DEVICE_NAME);if (IS_ERR(spinlock_devp->class_dev)){ret = PTR_ERR(spinlock_devp->class_dev);goto free_chrdev_class;}printk(KERN_INFO "My Spinlock Driver Init\n");return 0;free_chrdev_class:class_destroy(my_class);free_chrdev_region:unregister_chrdev_region(dev_no, 1);return ret;
}// 驱动退出函数
static void __exit my_driver_exit_module(void)
{cdev_del(&spinlock_devp->cdev);unregister_chrdev_region(dev_no, 1);kfree(spinlock_devp);printk(KERN_INFO "My Spinlock Driver Exited\n");
}module_init(my_driver_init_module);
module_exit(my_driver_exit_module);MODULE_AUTHOR("lidonghang-02");
MODULE_LICENSE("GPL");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/857129.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

河南大学24计算机考研数据,有三个学院招收计算机相关专业,都是考的408!

河南大学&#xff08;Henan University&#xff09;&#xff0c;简称“河大”&#xff0c;是河南省人民政府与中华人民共和国教育部共建高校&#xff0c;国家“双一流”建设高校&#xff0c;入选国家“111计划”、中西部高校基础能力建设工程、卓越医生教育培养计划、卓越法律人…

RFID优缺点和应用场景

一、RFID技术特点 优点 快速扫描&#xff1a;RFID识别器可以同时读写多个RFID标签&#xff0c;读取速度非常快。有源RFID系统的草图功能可以用于交互式服务&#xff0c;如过程跟踪和维护跟踪。 小型化和形状多样化&#xff1a;RFID标签向小型化和多样化方向发展&#xff0c;以…

怎么用二维码在线下载视频?视频用二维码下载的制作方法

怎么把视频转换成二维码之后还可以下载视频呢&#xff1f;现在使用二维码的方式来分享视频内容在很多行业和场景中都有应用&#xff0c;这种方式能够更加简单快捷的完成视频的传播分享&#xff0c;那么怎么让扫码者可以自由选择下载视频呢&#xff1f;下面来给大家分享扫码下载…

SQL server LAG方法改造 适配 SQL server 2008

LAG函数 方法 需要改造为 适配 SQL server 2008 ---改造前&#xff1a; select area_id, area_name, year, lag(cast(year as int ),1,1970) over (partition by area_id order by year) previous_year, …

深入探索C++中的AVL树

引言 在数据结构和算法的世界里&#xff0c;平衡二叉搜索树&#xff08;Balanced Binary Search Tree, BST&#xff09;是一种非常重要的数据结构。AVL树&#xff08;Adelson-Velsky和Landis发明的树&#xff09;就是平衡二叉搜索树的一种&#xff0c;它通过自平衡来维护其性质…

zookeeper + kafka消息队列

zookeeper kafka 消息队列 一、消息队列简介 1、什么是消息队列 消息队列&#xff08;Message Queue&#xff09;是一种用于跨进程或分布式系统中传递消息的通信机制。消息队列在异步通信、系统解耦、负载均衡和容错方面具有重要作用。 &#xff08;1&#xff09;特性 异步…

c++ 里构造函数的形参与数据成员的同名问题

如题&#xff0c;这时&#xff0c;或许在 java 里&#xff0c;会报语法错误。但在 c vs2019 开了 c20语法规范。这不再是错误。这样的好处是解决了咱们的起变量名的麻烦&#xff1a;重名现在已不是错误&#xff0c;编译器可以解决了。测试如下&#xff1a; 我们看看 c 编译器是…

如何正确理解和评估品牌价值?

在当今这个品牌林立的商业世界里&#xff0c;我们常常听到企业家们满怀憧憬地谈论品牌梦想。 但究竟是什么驱使这些企业去打造一个品牌&#xff0c;到底是市场的激烈竞争&#xff0c;还是内心的情感寄托&#xff1f;亦或是社会发展的必然趋势&#xff0c;引领我们追求超越产品…

C++ using 关键

先上代码 example 1&#xff1a; template <typename T> class Blocker : {public:using MessageType T;using MessageShrPtr std::shared_ptr<T>;using MessageQueue std::deque<MessageShrPtr>;using Callback std::function<void(const MessageS…

1969python房屋租赁管理系统mysql数据库Flask结构BootStrap布局计算机软件工程网页

一、源码特点 python Flask房屋租赁管理系统是一套完善的web设计系统mysql数据库 &#xff0c;对理解python编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 python flask 房屋租赁管理系统 开发环境pycharm mysql …

SpringBoot 项目,三种方式实现打印 sql 日志

方式一&#xff1a;指定mybatis日志级别 # application.yml mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 等价于application.properties mybatis.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl方式二、Mybatis-Plus…

酱香型白酒派系介绍

酱香型白酒作为中国传统白酒的重要流派&#xff0c;以其独特的酱香和复杂的酿造工艺而著称。在酱香型白酒中&#xff0c;形成了多个派系&#xff0c;各具特色。 以下是关于北派、茅派、川派和黔派等各个派系的详细介绍。 一、北派 地理位置&#xff1a;主要产于秦岭和淮河以…

AWS无服务器 应用程序开发—第十五章 CI/CD

创建一个针对 AWS Lambda 的 CI/CD 管道&#xff0c;可以大大提高开发和部署的效率和可靠性。以下是一个完整的示例&#xff0c;包括从 CodeCommit 开始的代码管理、使用 CodeBuild 进行单元测试、使用 CodePipeline 进行持续集成和持续部署 (CI/CD) 的具体步骤。 步骤 1&…

记一次通过脚本来实现自定义容器的自动重启

通过脚本来实现自定义容器的自动重启 1. 场景还原2. 自定义启动脚本3. 使用自定义脚本来作为容器启动的脚本4. 制作自定义脚本作为入口点的新镜像5. 测试新镜像启动是否走自定义启动脚本 1. 场景还原 现在我有一个自定义的Docker镜像&#xff0c;是基于基础镜像来构建的带有多…

【React】React 的StrictMode作用是什么,怎么使用?

React的<StrictMode>是一个用于在开发环境中检测潜在问题的工具,它可以帮助开发者在开发阶段识别并解决一些常见的编码问题,从而提高代码质量和应用的可靠性。以下是<StrictMode>的详细作用和使用方法: 作用 检测潜在问题:<StrictMode>会启用一些额外的…

Windows 图像处理组件(WIC)读写位深度24位的 bmp 文件

我写了类封装了一下。只是作业需要&#xff0c;缺少错误处理。 #include <wincodec.h>enum PixColor { B, G, R };struct ComEnv {ComEnv(){CoInitialize(nullptr);CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&fac));…

一文了解HarmonyOSNEXT发布重点内容

华为在2024年6月21日的开发者大会上正式发布了HarmonyOS NEXT版&#xff0c;这是华为在操作系统领域的一次重大飞跃&#xff0c;标志着华为在构建全场景智能生态方面的卓越成就。HarmonyOS NEXT版不仅带来了全新的系统架构和性能提升&#xff0c;还首次将AI能力融入系统&#x…

docker方式启动的redis如何使用自定义配置文件

本文参考这篇文章&#xff1a;参考 一、首先先下载默认的配置文件 wget http://download.redis.io/redis-stable/redis.conf 然后下载备份数据目录&#xff08;这个是用来做备份的&#xff0c;放在宿主机上&#xff09; mkdir -p /usr/local/docker/data 二、启动redis 下…

鸿蒙正在跨越“生态繁荣阈值”

作者 | 曾响铃 文 | 响铃说 先讲一个故事。 一个朋友曾经做了一个本地互联网装修平台&#xff0c;一边是装修服务的提供者——各工种工人等&#xff0c;一边是有装修需求的业主。这个平台要做独立生态&#xff0c;绕过旧有的装修公司渠道垄断&#xff0c;直接提供服务&#…

Android开发系列(六)Jetpack Compose之Box

Box是一个用来组合和控制子元素布局的组件。它可以在一个矩形区域内排列一个或多个子元素&#xff0c;并根据所提供的参数来控制它们的位置、大小和样式。 Box的功能类似传统的FrameLayout。 下面通过示例了解Box的使用方法&#xff0c;首先看一个最简单的示例&#xff0c;如下…