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很容易混淆。

转自: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

[cpp]  view plain copy
 
  1. static inline void __raw_spin_lock(raw_spinlock_t *lock)  
  2. {  
  3.         preempt_disable();  
  4.         spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);  
  5.         LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);  
  6. }  

spin_lock_irq的调用关系

    spin_lock_irq

                |

               +-------> raw_spin_lock_irq

                                           |

                                          +---------> _raw_spin_lock_irq

                                                                      |

                                                                      +------------> __raw_spin_lock_irq

[cpp]  view plain copy
 
  1. static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)  
  2. {  
  3.         local_irq_disable();  
  4.         preempt_disable();  
  5.         spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);  
  6.         LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);  
  7. }  

可以看出来他们两者只有一个差别:是否调用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

【作者】 张昺华
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
目录
相关文章
|
大数据 Python
Python中for循环的嵌套应用
Python中for循环的嵌套应用
334 1
记Vue3在table使用dropdown的写法
记Vue3在table使用dropdown的写法
408 0
|
存储 SQL 关系型数据库
MySQL主键约束详解
MySQL是一个强大的关系型数据库管理系统,用于存储和管理大量数据。在数据库中,主键约束是一项非常重要的概念,它有助于确保数据的完整性和唯一性。本文将详细介绍MySQL主键约束,包括什么是主键、为什么需要主键、如何创建主键以及主键的最佳实践。
1112 1
关于Neo4j的使用及其基本命令
关于Neo4j的使用及其基本命令
321 0
|
关系型数据库 MySQL 数据库
主从同步设置的重要参数log_slave_updates
说明:最近部署了mysql的集群环境,详细如下M01和M02为主主复制,M01和R01为主从复制;在测试的过程中发现了以下问题: 1、M01和M02的主主复制是没有问题的(从M01写入数据能同步到M02,从M02写入数据能够同步到M01); 2、主从同步的时...
2314 0
|
Java Python
Python 生成、解析二维码
Python 生成、解析二维码
311 0
|
存储 关系型数据库 MySQL
MySQL索引失效及避免策略:优化查询性能的关键
MySQL索引失效及避免策略:优化查询性能的关键
767 3
|
存储 固态存储 数据可视化
|
存储 安全 API
使用KMS为Apollo配置中心敏感配置加密的最佳实践
使用KMS为Apollo配置中心敏感配置加密的最佳实践
2450 4
|
监控 数据可视化 安全
ERP系统中的企业绩效管理与KPI指标设定
【7月更文挑战第25天】 ERP系统中的企业绩效管理与KPI指标设定
791 0