linux驱动开发笔记_自旋锁

自旋锁介绍

自旋锁(spin lock)是一种典型的对临界资源进行互斥访问的手段。如果A执行单元首先进入例程,他将持有自旋锁,当B执行单元试图进入同一个例程时,将获悉自旋锁已经被持有,然后需要等待A单元释放后,方可进入。

相关操作函数

1.定义自旋锁

spinlock_t    lock;  

2.初始化自旋锁

spin_lock_init(lock);

3 获得自旋锁

spin_lock(lock);

该宏如果能够立即获得锁。它就马上返回;否则,他就将在其中自旋,直到该自旋锁的保持者释放。

spin_trylock(lock);

该宏尝试获得自旋锁lock,如果能够立即获得锁,它则返回true, 否则返回false,实际上并不在原地打转。

4.释放自旋锁

spin_unlock(lock);

自旋锁的一般使用方法:

spinlock_t  lock;
spin_lock_init(lock);

spin_lock(lock);
....... /*临界区*/
spin_unlock(lock);

较重要知识点

1.自旋锁主要针对于 SMP或者 单CPU但内核可抢占的情况,对于单CPU和内核不支持抢占的系统,自旋锁退化为空操作。

2.在自旋锁的持有期间,对应内核的抢占将被禁止。即不会被别的进程打扰。

3.在自旋锁期间不能调用可能引起进程调度的函数比如说copy_from_user,kmalloc(),msleep()等。
如果线程A 在持有锁期间进入了休眠状态,那么线程A 会自动放弃CPU 使用权。线程B 开始运行,线程B也想要获取锁,但是此时锁被A 线程持有,而且内核抢占还被禁止了!线程B 无法被调度出去,那么线程A 就无法运行,锁也就无法释放,好了,死锁发生了!

4.在自旋锁期间,需要禁止中断。如果当前代码被中断打断,而中断处理程序中也请求了这个锁, 就会造成死锁。

5.自旋锁还会收到底半部(下半部)的影响。

为了解决上面的4.5点造成的问题,需要在使用自旋锁的同时,关闭掉该核心的中断功能或者底半部功能,由此得到了自旋锁的衍生函数如下:

spin_lock_irq() =  spin_lock() + local_irq_disable()
spin_unlock_irq() =  spin_unlock() + local_irq_enable()

spin_lock_irqsave() =  spin_lock() + local_irq_save()
spin_unlock_irqrestore() =  spin_unlock() + local_irq_restore()

spin_lock_bh() = spin_lock() + local_bh_disable()
spin_unlock_bh() = spin_unlock() + local_bh_enable()

主要用法

1.一般在进程上下文中,调用spin_lock_irqsave() / spin_unlock_irqrestore() ;
2.一般在中断上下文中,调用spin_lock() / spin_unlock() ;

这样,不管是核内还是核间,都杜绝了并发的可能性。

使用注意

1.自旋锁适用环境为占锁时间较短的情况,因为CPU此时不做任何操作,只是在循环等待,如果自旋锁时间占用过长,会引起CPU效率降低。
2.错误使用自旋锁可能会造成死锁。 常见问题是递归使用自旋锁。
3.自旋锁锁定期间不能调用引起进程调度的函数。如:copy_from_user() 、copy_to_user()、Kmalloc()、和msleep() 等函数。可能引起内核的崩溃。
4. 自旋锁在编程时,编程者应该认为自己所使用的CPU是多核的情况。

读写自旋锁(新)

常规自旋锁不关心临界区究竟在做什么操作,不管读写都一视同仁。但实际上共享资源的并发访问,同时读取是没有什么问题的。只是不能同时写,或者同时读写。读写自旋锁就是为了解决这个问题。

1.定义和初始化读写自旋锁

rwlock_t   my_rwlock;
rwlock_init(&my_rwlock);   /*动态初始化*/

2.读锁定

void read_lock(rwlock_t  *lock);
void read_lock_irqsave(rwlock_t *lock, unsigned long flags );
void read_lock_irq(rwlock_t  *lock);
void read_lock_bh(rwlock_t  *lock);

3.读解锁
在这里插入图片描述4.写锁定
在这里插入图片描述5.写解锁
在这里插入图片描述

读写锁的一般使用方法

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值