当前位置: 首页 > news >正文

【讯为Linux驱动开发】6.自旋锁spinlock

【自旋锁】

线程A获取自旋锁后,B假如想获取自旋锁则只能原地等待,仍占用CPU不会休眠,直到获取自旋锁为止。

【函数】

DEFINE SÃINLOCK(spinlock t lock)   定义并初始化一个变量
int spin lock init(spinlock t*lock)   初始化自旋锁
void spin lock(spinlock t *lock)    获取自旋锁。也叫做加锁
void spin_unlock(spinlock t *lock)    释放自旋锁,也叫做解锁
int spin trylock(spinlock t *lock)    尝试获取自旋锁,如果没有获取到就返回0
int spin is locked(spinlock t *lock)   检查自旋锁是否被获取,如果没有被获取就返回非0,否则返回0

【如何使用】

  1. 访问临界资源时首先申请自旋锁
  2. 获取自旋锁后进入临界区,获取不到就等待
  3. 退出临界区释放自旋锁 

【临界区】

【注意事项】 

  1. 原地等待消耗CPU。临界区代码一定不能多。
  2. 临界区中不可以调用会导致进程休眠的函数,否则可能死锁
  3. 一般用于多核CPU

【实验】

/* 定义一个自旋锁 */
static spinlock_t my_spinlock;
static flag = 1;  //标志位模拟驱动有没有被用到static int cdev_open(struct inode *inode, struct file *filp)
{spin_lock(my_spinlock);  //加锁if(flag != 1){spin_unlock(my_spinlock); return -EBUSY;}flag = 0;spin_unlock(my_spinlock);  //解锁file->private_data = &dev1; //指向设备结构体return 0;
}static int cdev_release(struct inode *inode, struct file *filp)
{spin_lock(my_spinlock);  //加锁flag = 1;spin_unlock(my_spinlock);  //解锁      
}

【验证】

int main(int argc, char *argv[])
{int fd1;char buf1[32] = "ni hao test1!";fd1 = open("/dev/test1", HELLO);  /* 打开设备节点1 */   sleep(5);  /* 延时5秒,为了实验效果*/close(fd1);return 0;  
}

【实验结果】

A打开驱动程序,假设执行到FLAG = 0,此时又有B要使用驱动,那么Flag = 0意味着A正在使用驱动,同时Flag =0 使得flag !=1所以B进不去驱动,只能报错。

当等A使用驱动完毕,触发release函数,flag被置为1,才意味着其他程序可以使用驱动了。

相关文章:

  • 【LeetCode滑动窗口算法】长度最小的子数组 难度:中等
  • ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 探测效果(地图探测、地图窥探)
  • 史上最全盘点:一文告诉你什么是erp?erp系统厂商分别有哪些?
  • 47-3 等保测评报告编写
  • Windows环境下JDK安装及环境变量配置指南
  • 详解 Flink Table API 和 Flink SQL 之时间特性
  • Apache Pulsar 从入门到精通
  • ORACLE中ROWNUM的机制和注意细节(避坑
  • Codeforces Round 952 (Div. 4)
  • 【上海大学计算机组成原理实验报告】七、程序转移机制
  • 网络安全入门教程(非常详细)从零基础入门到精通,看完这一篇你就是网络安全高手了。
  • keil调试过程中遇到的问题及栈分析遇到的问题
  • C++回溯算法
  • 安装Pygame
  • 2024.06.13
  • [deviceone开发]-do_Webview的基本示例
  • Android组件 - 收藏集 - 掘金
  • avalon2.2的VM生成过程
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • es6要点
  • HTTP--网络协议分层,http历史(二)
  • Java IO学习笔记一
  • Javascript设计模式学习之Observer(观察者)模式
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Selenium实战教程系列(二)---元素定位
  • TCP拥塞控制
  • Theano - 导数
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 编写符合Python风格的对象
  • 从零开始在ubuntu上搭建node开发环境
  • 代理模式
  • 构建二叉树进行数值数组的去重及优化
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 关于 Cirru Editor 存储格式
  • 机器学习学习笔记一
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 1.Ext JS 建立web开发工程
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • #每日一题合集#牛客JZ23-JZ33
  • (4)事件处理——(7)简单事件(Simple events)
  • (day6) 319. 灯泡开关
  • (js)循环条件满足时终止循环
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (第27天)Oracle 数据泵转换分区表
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (六)激光线扫描-三维重建
  • (推荐)叮当——中文语音对话机器人
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转载)虚函数剖析
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .net MVC中使用angularJs刷新页面数据列表
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)