自旋锁与信号量

自旋锁一般这样被使用,如下所示:
//定义一个自旋锁
spinlock_t lock;
spin_lock_init(&lock);
spin_lock (&lock) ; //获取自旋锁,保护临界区
...//临界区
spin_unlock (&lock) ; //解锁

自旋锁主要针对SMP或单CPU但内核可抢占的情况,对于单CPU和内核不支持
抢占的系统,自旋锁退化为空操作。在单CPU 和内核可抢占的系统中,自旋锁持有
期间内核的抢占将被禁止。由于内核可抢占的单CPU 系统的行为实际很类似于SMP
系统,因此,在这样的单CPU系统中使用自旋锁仍十分必要。

 

驱动工程师应谨慎使用自旋锁,而且在使用中还要特别注意如下几个问题。
1. 自旋锁实际上是忙等锁,当锁不可用时,CPU一直循环执行“测试并设置”
该锁直到可用而取得该锁,CPU在等待自旋锁时不做任何有用的工作,仅仅
是等待。因此,只有在占用锁的时间极短的情况下,使用自旋锁才是合理的。
当临界区很大或有共享设备的时候,需要较长时间占用锁,使用自旋锁会降
低系统的性能。
2.自旋锁可能导致系统死锁。引发这个问题最常见的情况是递归使用一个自旋
锁,即如果一个已经拥有某个自旋锁的CPU 想第二次获得这个自旋锁,则
该CPU 将死锁。此外,如果进程获得自旋锁之后再阻塞,也有可能导致死
锁的发生。copy_from_user()、copy_to_user()和kmalloc()等函数都有可能引
起阻塞,因此在自旋锁的占用期间不能调用这些函数。

 

信号量一般这样被使用,如下所示:
//定义信号量
DECLARE_MUTEX(mount_sem);
down(&mount_sem);//获取信号量,保护临界区
...
critical section //临界区
...
up(&mount_sem);//释放信号量

Linux自旋锁和信号量所采用的“获取锁—访问临界区—释放锁”的方式存在
于几乎所有的多任务操作系统之中。

自旋锁和信号量都是解决互斥问题的基本手段,面对特定的情况,应该如何进行
选择呢?选择的依据是临界区的性质和系统的特点。
从严格意义上说,信号量和自旋锁属于不同层次的互斥手段,前者的实现依
赖于后者。在信号量本身的实现上,为了保证信号量结构存取的原子性,在多
CPU中需要自旋锁来互斥。
信号量是进程级的,用于多个进程之间对资源的互斥,虽然也是在内核中,但是
该内核执行路径是以进程的身份,代表进程来争夺资源的。如果竞争失败,会发生进
程上下文切换,当前进程进入睡眠状态,CPU将运行其他进程。鉴于进程上下文切换
的开销也很大,因此,只有当进程占用资源时间较长时,用信号量才是较好的选择。
当所要保护的临界区访问时间比较短时,用自旋锁是非常方便的,因为它节省上
下文切换的时间。但是CPU得不到自旋锁会在那里空转直到其他执行单元解锁为止,
所以要求锁不能在临界区里长时间停留,否则会降低系统的效率。
由此,可以总结出自旋锁和信号量选用的3 项原则。
1.当锁不能被获取时,使用信号量的开销是进程上下文切换时间Tsw,使用自
旋锁的开销是等待获取自旋锁(由临界区执行时间决定)Tcs,若Tcs 比较小,
应使用自旋锁,若Tcs很大,应使用信号量。
2. 信号量所保护的临界区可包含可能引起阻塞的代码,而自旋锁则绝对要避免
用来保护包含这样代码的临界区。因为阻塞意味着要进行进程的切换,如果
进程被切换出去后,另一个进程企图获取本自旋锁,死锁就会发生。
3.信号量存在于进程上下文,因此,如果被保护的共享资源需要在中断或软中
断情况下使用,则在信号量和自旋锁之间只能选择自旋锁。当然,如果一定
要使用信号量,则只能通过down_trylock()方式进行,不能获取就立即返回
以避免阻塞。

并发和竞态广泛存在,中断屏蔽、原子操作、自旋锁和信号量都是解决并发问题
的机制。中断屏蔽很少单独被使用,原子操作只能针对整数进行,因此自旋锁和信号
量应用最为广泛。
自旋锁会导致死循环,锁定期间不允许阻塞,因此要求锁定的临界区小。信号量
允许临界区阻塞,可以适用于临界区大的情况。
读写自旋锁和读写信号量分别是放宽了条件的自旋锁和信号量,它们允许多个执
行单元对共享资源的并发读。

 参考:自旋锁和互斥体

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值