spin_lock、spin_lock_irq、spin_lock_irqsave区别【转】
转自:http://blog.csdn.net/luckywang1103/article/details/42083613
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, 0, 0, _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, 0, 0, _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前是关中断
转自: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区别
void spin_lock(spinlock_t *lock); void spin_lock_irq(spinlock_t *lock); void spin_lock_irqsave(spinl ...
- 那些情况该使用它们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 ...
随机推荐
- IEnumerable和IQueryable的区别
转自:http://www.cnblogs.com/fly_dragon/archive/2011/02/21/1959933.html IEnumerable接口 公开枚举器,该枚举器支持在指定类型 ...
- Linux命令行–初识Linux shell
shell及脚本简介 GNU/Linux shell 是个交互工具,它为用户提供了启动程序.管理文件系统上的文件以及管理运行在Linux系统上的进程的途径 . shell的核心是命令行提示符 它是s ...
- EncodingAESKey
关键字:EncodingAESKey 公众平台消息体签名及加解密方案概述 1.新增消息体签名验证,用于公众平台和公众账号验证消息体的正确性 2.针对推送给微信公众账号的普通消息和事件消息,以及推送给设 ...
- ucenter 整合同步登录的内部实现原理及thinkphp整合ucenter
1.用户登录discuz,通过logging.php文件中的函数uc_user_login对post过来的数据进行验证,也就是对username和password进行验证.2.如果验证成功,将调用位于 ...
- 面向对象编程(十)——继承之Super关键字及内存分析
Super关键字
- 维护计划生成的SSIS包存储在哪
首先理解导入导出包的基本概念:http://technet.microsoft.com/zh-cn/library/ms141772(v=SQL.110).aspx包既可以保存在SQL Server ...
- [3D]绘制线
数据实体: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sy ...
- MFC和GDI+一起使用
VS2010,新建MFC项目,在头文件stdafx.h中添加: #include <gdiplus.h> using namespace Gdiplus; #pragma comment ...
- Redis "MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk"问题的解决
异常详细信息 Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: MISCO ...
- Go 性能分析
上线一定要用压力测试,才能知道自己的承受度是多少,不然出了问题,就各种排查. http://www.tuicool.com/articles/NVRJrm 通过jmeter压力测试,发现打印请求参数消 ...