linux spin_lock注意事项

本文介绍了Linux内核中用于并发访问控制的spin_lock机制。spin_lock是一种忙等待的锁,适用于需要快速上下文切换且不涉及I/O操作的场景。在临界区使用spin_lock时,如果出现睡眠或中断,可能会导致死锁或其他问题。为解决这个问题,可以使用spin_lock_irq()来关闭中断,防止死锁。理解并合理使用spin_lock是驱动开发中的关键技能。
摘要由CSDN通过智能技术生成

原文地址:https://blog.csdn.net/madannasf/article/details/103246042

一、概述
在kernel中,发生并发访问的发生源主要为一下4种方式
1、中断和异常,中断发生之后,中断处理函数与被中断进程之间有可能会出现资源并发访问
2、软中端以及tasklet,软中断以及任务调度都会打断当前的进程,从而发生资源的并发性访问
3、内核抢占,内核抢占也是会打断当前的进程,从而造成资源的并发性访问
4、smp,多个CPU也会对同一个资源进行并发性的访问。
为了解决资源并发性的访问从而造成意料之外的现象,linux内核提供了几种保护机制。
比如spinlock,atomic,semphorema,mutex和 write read lock以及rcu。
今天我们主要聊一聊spin_lock这个在驱动中使用较为常见的资源保护机制

二、spin_lock介绍
2.1 引入
对引用计数这些如果使用lock机制,就会造成额外的系统开销,但是在驱动中,我们大多数都是资源的拷贝,解析这些需要大量CPU资源的操作,同时也需要保护这部分数据的操作的有效性,spin_lock是一个非常不错的选择。
spin_lock是一个忙等待的工作方式,如果两个进程同时访问资源,但是其中一个进程以及获取到该资源后,就会对资源加上一把自旋锁,另外一个资源只有在死循环等待前一个进程释放该锁之后才可以对资源进行访问,所以:spin_lock是忙等待的工作方式。

2.2、一些小谈
**假设:**在spin_lock的临界区出现了睡眠,tasklet等会出现什么样的后果勒?
答:1、tasklet或者睡眠之后,下一个进程可能会访问临界区中的资源,从而进行加spin_lock,这就造成了我们常见的死锁问题了。
2、spin_lock设计是一个忙等待机制,如果临界出现了进程的切换或者调度,都与spin_lock的设计机制相悖。
**假设2:**如果在spin_lock的临界区发生了外部硬件中断该如何处理
答:这时候我们需要引入spin_lock的变种了,spin_lock_irq()了,spin_lock_irq()会在获取spin_lock之前会关闭本地中断,从而避免了死锁问题。

总结:
合理的使用spin_lock是每一个驱动工程师应该学会的机能,在普通函数中防止资源的并发性使用spin_lock,但是在中断中防止资源的并发性使用spin_lock_irq(),它会在spin_lock之前将本地的中断关闭,从而避免了spin_lock的死锁发生。
————————————————
版权声明:本文为CSDN博主「var.zhou」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/madannasf/article/details/103246042

spin_lock() 和 spin_lock_irqsave() 都是 Linux 内核中用于保护共享资源的自旋锁函数,它们的区别在于是否对中断进行处理。 spin_lock() 函数会获取自旋锁,并禁用本地 CPU 的中断。这意味着,如果在获取自旋锁的过程中发生了中断,中断处理程序将无法运行,直到自旋锁被释放。因此,spin_lock() 主要用于在中断被禁用的情况下保护共享资源,以防止其他 CPU 并发访问。 而 spin_lock_irqsave() 函数则会获取自旋锁,并保存本地 CPU 的中断状态。这意味着,在获取自旋锁的过程中,中断可以被触发,但是中断处理程序不能访问被保护的共享资源,因为它们也会尝试获取自旋锁。因此,spin_lock_irqsave() 主要用于在中断被启用的情况下保护共享资源。 在使用 spin_lock_irqsave() 函数时,需要在获取自旋锁的同时保存中断状态,并在释放自旋锁的同时恢复中断状态,以避免出现中断状态被篡改的情况。常见的用法是: ```c spinlock_t my_lock; unsigned long flags; spin_lock_irqsave(&my_lock, flags); // 获取自旋锁并保存中断状态 // 在这里进行对共享资源的访问 spin_unlock_irqrestore(&my_lock, flags); // 释放自旋锁并恢复中断状态 ``` 总之,spin_lock() 适用于在禁用中断的情况下保护共享资源,而 spin_lock_irqsave() 适用于在启用中断的情况下保护共享资源,它们的使用方式略有不同,需要根据具体情况选择合适的函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值