解决驱动开发中并发和竞争中的问题----------自旋锁

什么是自旋锁

是指临界区资源被持有锁线程A拥有的时候,别的线程B只能原地等待不会进入睡眠,直到A释放锁,那么A才可以访问临界区资源

注意:自旋锁一般是用在等待时间比较短的地方,如果等待时间较长的话一般考虑使用信号量

结构体:spinlock_t

在这里插入图片描述

相关API函数

下面的API是不考虑中断情况下的
在这里插入图片描述
主要是下面两个函数

获得锁函数 void spin_lock(spinlock_t *lock) 获取指定的自旋锁,也叫做加锁

解锁函数 void spin_unlock(spinlock_t *lock) 释放指定的自旋锁

注意:上面的自旋锁API函数适用于SMP或支持抢占的单CPU下线程之间的并发访问, 也就是用于线程与线程之间(不考虑中断),被自旋锁保护的临界区一定不能调用任何能够引起睡眠和阻塞的 API 函数,否则的话会可能会导致死锁现象的发生

注意发生死锁:
由于获得锁之后内核会自动禁止抢占,如果线程A进入睡眠的话就相当于放弃了CPU,那么此时B线程就会运行,此时B也想获得锁,但是线程A并没有释放掉锁,并且A由于禁止抢占式不能被唤醒,所以B只能在外面等待,所以就出现死锁

考虑中断的情况
如果线程之间来了个中断,又会是什么情况呢
在这里插入图片描述
线程 A 先运行,并且获取到了 lock 这个锁,当线程 A 运行程序的时候中断发生了,中断抢走了CPU 使用权。右边的中断服务函数也要获取 lock 这个锁, 但是这个锁被线程 A 占有着,中断就会一直自旋,等待锁有效。但是在中断服务函数执行完之前,线程 A 是不可能执行的,线程 A 说“你先放手”,中断说“你先放手”,场面就这么僵持着,死锁发生!

最好的解决方法就是获取锁之前关闭本地中断

即调用下面的函数获得锁即可
在这里插入图片描述

使用自旋锁一般步骤

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

注意事项:

在这里插入图片描述

总结:
1)自旋锁的使用可以在中断中,如果有中断的话必须使用考虑中断的API获得锁,不然会出现死锁,
2)自旋锁必须是等待时间比较短,因为自旋锁会一直占用CPU,如果需要等待长时间即进入睡眠的话那就考虑信号量,下面一篇介绍信号量
3)自旋锁不能使用睡眠或阻塞的相关函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知道起个啥名“”

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值