spin_lock、spin_lock_irq、spin_lock_irqsave区别
void spin_lock(spinlock_t *lock);
void spin_lock_irq(spinlock_t *lock);
void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);
1、spin_lock与spin_lock_irq区别
在Linux内核中何时使用spin_lock,何时使用spin_lock_irqsave很容易混淆。首先看一下代码是如何实现的。
spin_lock的调用关系
spin_lock
|
+ -----> raw_spin_lock
|
+------> _raw_spin_lock
|
+--------> __raw_spin_lock
static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
preempt_disable();
spin_acquire(&lock->dep_map, , , _RET_IP_);
LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
}
spin_lock_irq的调用关系
spin_lock_irq
|
+-------> raw_spin_lock_irq
|
+---------> _raw_spin_lock_irq
|
+------------> __raw_spin_lock_irq
static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)
{
local_irq_disable();
preempt_disable();
spin_acquire(&lock->dep_map, , , _RET_IP_);
LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
}
可以看出来他们两者只有一个差别:是否调用local_irq_disable()函数, 即是否禁止本地中断。
在任何情况下使用spin_lock_irq都是安全的。因为它既禁止本地中断,又禁止内核抢占。
spin_lock比spin_lock_irq速度快,但是它并不是任何情况下都是安全的。
举个例子:进程A中调用了spin_lock(&lock)然后进入临界区,此时来了一个中断(interrupt),
该中断也运行在和进程A相同的CPU上,并且在该中断处理程序中恰巧也会spin_lock(&lock)
试图获取同一个锁。由于是在同一个CPU上被中断,进程A会被设置为TASK_INTERRUPT状态,
中断处理程序无法获得锁,会不停的忙等,由于进程A被设置为中断状态,schedule()进程调度就
无法再调度进程A运行,这样就导致了死锁!
但是如果该中断处理程序运行在不同的CPU上就不会触发死锁。 因为在不同的CPU上出现中断不会导致
进程A的状态被设为TASK_INTERRUPT,只是换出。当中断处理程序忙等被换出后,进程A还是有机会
获得CPU,执行并退出临界区。
所以在使用spin_lock时要明确知道该锁不会在中断处理程序中使用。
2、spin_lock_irq与spin_lock_irqsave区别
spin_lock_irqsave在进入临界区前,保存当前中断寄存器flag状态,关中断,进入临界区,在退出临界区时,把保存的中断状态写回到中断寄存器。
spin_lock_irq在进入临界区前不保存中断状态,关中断,进入临界区,在退出临界区时,开中断。
spin_lock_irqsave锁返回时,中断状态不会被改变,调用spin_lock_irqsave前是开中断返回就开中断。
spin_lock_irq锁返回时,永远都是开中断,即使spin_lock_irq前是关中断
总结:
01)spin_lock_irq:既禁止本地中断,又禁止内核抢占;加锁后禁止中断,直到解锁后允许中断,故此该功能可保证时域的独立性;(中断中没有该标记锁的时候不会对中断有影响)
02)spin_lock:快于spin_lock_irq,但不禁止中断,当在一个cpu下发生中断后,在时域上可打破该锁环境,当在对应中断服务函数中有同样锁的时候,因为得不到解锁,可能导致死锁;(对中断完整性用影响)
03)spin_lock_irqsave:对中断状态有保护特性;(对中断完整性没有影响)
转自:http://blog.csdn.net/zhanglei4214/article/details/6837697
http://blog.csdn.net/lbo4031/article/details/8894830
spin_lock、spin_lock_irq、spin_lock_irqsave区别的更多相关文章
- spin_lock、spin_lock_irq、spin_lock_irqsave区别【转】
转自:http://blog.csdn.net/luckywang1103/article/details/42083613 void spin_lock(spinlock_t *lock); voi ...
- 那些情况该使用它们spin_lock到spin_lock_irqsave【转】
转自:http://blog.csdn.net/wesleyluo/article/details/8807919 权声明:本文为博主原创文章,未经博主允许不得转载. Spinlock的目的是用来同步 ...
- spin_lock 和 spin_lock_irqsave
一 .spin_lock_irqsave . spin_unlock_irqrestore 如果自旋锁在中断处理函数中被用到,那么在获取该锁之前需要关闭本地中断,spin_lock_irqsave ...
- spin_lock & mutex_lock的区别?
http://blog.csdn.net/sunnytina/article/details/7615520 为什么需要内核锁? 多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是 ...
- 【转】spin_lock & mutex_lock的区别? .
原文网址:http://blog.csdn.net/wilsonboliu/article/details/19190861 本文由该问题引入到内核锁的讨论,归纳如下 为什么需要内核锁? 多核处理 ...
- 锁(1):spin_lock & mutex_lock的区别? .
为什么需要内核锁? 多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是可以访问所有内核数据的,因此要对共享数据进行保护,即互斥处理 有哪些内核锁机制? (1)原子操作 atomic ...
- spin_lock & mutex_lock的区别? 【转】
转自:http://blog.csdn.net/wilsonboliu/article/details/19190861 本文由该问题引入到内核锁的讨论,归纳如下 为什么需要内核锁? 多核处理器下 ...
- 自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave
自旋锁和互斥锁的区别是,自旋锁不会引起睡眠,所以可用于不能休眠的代码中(如IRQ) 自旋锁保持期间抢占失效,而信号量保持期间可以被抢占 定义 spinlock_t lock; init #define ...
- 关于内核中spinlock的一些个人理解 【转】
由于2.6内核可以抢占,应该在驱动程序中使用 preempt_disable() 和 preempt_enable(),从而保护代码段不被抢占(禁止 IRQ 同时也就隐式地禁止了抢占).preempt ...
随机推荐
- 【前端学习笔记】2015-09-11~~~~ js中ajax请求返回案例
<body><textarea id='a' rows=100 cols=300>result:</textarea>><script>var a ...
- Spring学习之路——简单入门HelloWorld
Spring简单介绍 Spring是一个提供了解决J2EE问题的一站式框架. Spring的核心是反转控制,通过配置文件完成业务对象之间的依赖注入,他鼓励一个良好的习惯,就是注入对接口编程而不是对类编 ...
- css3 nth-child 与 nth-of-type 的区别
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1709 一.深呼吸,直 ...
- Js 流程控制
流程控制 顺序.分支.循环 顺序结构 代码一行一行从上往下执行并解析 分支结构 if语句 switch语句 if语句 单分支 if(条件表达式){ //语句块 } 含义:当条件表达式为真的时候就执行里 ...
- profile, bashrc, source, setup.*sh
一. source: 命令是使该文件立刻执行,这样刚才做的修改就可以立即生效了,否则要重新启动系统修改才能生效.(执行其后命令使之立即生效,不用重启) 二.bashrc: 1.linux系统:/etc ...
- Windows使用Telnet连接Linux服务器初探(待实践)
在Windows下可以适用Telnet连接Linux服务器,但是前提是在Linux下需要安装Tlenet-Server.还要开启防火的23端口.搞定之后就可以用telnet IP进行连接. 但是,我发 ...
- python各种类型转换
python各种类型转换 学习了:https://blog.csdn.net/shanliangliuxing/article/details/7920400 https://blog.csdn.ne ...
- 生成和解析txt文件
package txt; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; imp ...
- js跳出循环的方法区别( break, continue, return ) 及 $.each 的(return true 和 return false)
js编程语法之break语句: break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句. 由于它是用来退出循环或者switch语句,所以只有当它出现在这些语句时,这种形式的 ...
- java8 stream sorted
1.对象类型配列 List<Person> list = Arrays.asList( new Person(22, "shaomch", "man" ...