前面原子操作进行了讲解, 并使用原子整形操作对并发与竞争实验进行了改进,但是原子操作只能对整形变量或者位进行保护, 而对于结构体或者其他类型的共享资源, 原子操作就力不从心了, 这时候就轮到自旋锁的出场了。
两个 app 应用程序之间对共享资源的竞争访问引起了数据传输错误, 而在 Linux 内核中, 提供了四种处理并发与竞争的常见方法:
分别是原子操作、 自旋锁、 信号量、 互斥体, 这里了解下原子操作
文章目录
自旋锁概念
自旋锁是一种低级的同步原语,用于在多处理器系统中保护共享资源。与互斥锁不同,当一个线程尝试获取已被占用的自旋锁时,它不会阻塞或睡眠,而是会在一个循环中不断检查锁的状态(即"自旋"),直到锁变为可用状态。
工作原理
-
尝试获取锁:线程尝试通过原子操作获取锁
-
锁可用:获取成功,线程继续执行临界区代码
-
锁被占用:线程进入忙等待循环,不断检查锁状态
-
锁释放:当锁持有者释放锁后,等待线程可以获取锁
特点
-
忙等待:不放弃CPU,持续检查锁状态
-
短临界区:适合保护执行时间很短的代码段
-
无上下文切换:避免了线程切换的开销
-
多处理器有效:在单处理器系统上可能浪费CPU周期
常用API
#include <linux/spinlock.h>
// 定义和初始化
spinlock_t my_lock;
spin_lock_init(&my_lock);
// 获取锁
spin_lock(&my_lock); // 获取锁,禁用本地 CPU 中断
spin_lock_irq(&my_lock); // 获取锁并禁用硬件中断
spin_lock_irqsave(&my_lock, flags); // 保存中断状态并获取锁
// 释放锁
spin_unlock(&my_lock); // 释放锁
spin_unlock_irq(&my_lock); // 释放锁并恢复中断
spin_unlock_irqrestore(&my_lock, flags); // 释放锁并恢复之前的中断状态
// 尝试获取锁
int spin_trylock(&my_lock); // 非阻塞尝试获取锁,成功返回非零
参考资料
接下来还是以前面字符设备 动态参数传递实验为基础,打开访问字符设备实验。 所以以前知识点 建议了解
在字符设备这块内容,所有知识点都是串联起来的,需要整体来理解,缺一不可,建议多了解一下基础知识
驱动-申请字符设备号
驱动-注册字符设备
驱动-创建设备节点
驱动-字符设备驱动框架
驱动-杂项设备
驱动-内核空间和用户空间数据交换
驱动-文件私有数据
Linux驱动之 原子操作
Linux驱动—原子操作
驱动-原子操作实验
实验源码 spinlock.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/atomic.h>
#include <linux/errno.h>
static spinlock_t spinlock_test;//定义spinlock_t类型自旋变量
static int flag=1;
static int open_test(struct inode *inode,struct file *file)
{
spin_lock(&spinlock_test); //自旋枷锁
if(flag!=1){
//判断标志位flag 的值是否等于1
spin_unlock(&spinlock_test);
return -EBUSY;
}
flag=0

最低0.47元/天 解锁文章
904

被折叠的 条评论
为什么被折叠?



