linux内核中访问共享资源
访问共享资源的代码区域称为临界区,临时以某种互斥机制加以保护。中断屏蔽、原子操作
自旋锁和信号量是Linux设备驱动中可采用的互斥途径。
在单CPU范围内避免竞态的一种简单方法是在进入临界区之前屏蔽系统的中断。
CPU一般都具备屏蔽中断和打开中断的功能。
中断屏蔽的使用方法:
Local_irq_disable(); //屏蔽中断--->和它不同的是local_irq_save除了禁止中断操作以外还可以保存目前CPU的中断位信息
......
临界区
......
Local_irq_enable(); //开中断--->local_irq_restore进行的是与local_irq_save相反的操作。
要求:在屏蔽了中断之后,当前的内核执行路径应当尽快地执行完临界区的代码。
如果只是想禁止中断的底半部,应当使用local_bh_disable(),使能local_bh_disable()
禁止的底半部应该调用local_bh_enable();
原子操作:指的是在执行过程中不会被别的代码路径所中断的操作
内核中有一些函数分为两类,分别针对位和整型变量进行原子操作。共同点:在任何情况下操作都是原子的,内核代码可以安全地调用
它们而不被打断。都是依赖底层CPU的原子操作来实现的。所以这些函数都与CPU的架构密切相关。
SMP:多处理器结构的简称.
自旋锁的作用:
自旋锁spin_lock是一种对临界资源进行互斥访问的典型手段,这个名字是由于它的工作方式。
要获得自旋锁,在CPU上运行的代码需要先执行一个原子操作,该操作测试并设置某个内存变量,
由于它是原子操作,所以在操作完成之前其它执行单元不可能访问这个内存变量。
如果测试结果表明锁已经空闲,则程序获得这个自旋锁并继续执行;如果测试结果表明锁
仍被占用,程序将在一个小循环内重复这个"测试并设置"操作,即进行所谓的“自旋”,通俗的说
就是在原地打转,当自旋锁的持有者通过重新设置该变量释放这个自旋锁后,某个等待的"测试并设置"的操作
向其调用者报告锁已经被释放。
自旋锁操作主要针对SMP或单CPU但内核可抢占的情况,对于单CPU和内核不支持抢占的系统,自旋锁退化为空操作。
在单CPU和内核可抢占的系统中,自旋锁持有期间内核的抢占将被禁止。由于内核抢占的单CPU兄的行为实际
很类似于SMP系统,隐私在这样的单CPU系统中使用自旋锁就十分必要。
Linux系统中与自旋锁相关的操作主要有以下4种:
定义一个自旋锁:
Spinlock_t spin ;
初始化自旋锁:
Spin_lock_init(lock) ;
获得自旋锁:
Spin_lock(lock);
如果能立即获得锁,就马上返回,否则,它将自旋,直到该自旋锁的保持者释放。
Spin_trylock(lock);
尝试获得自旋锁lock,如果可以立即获得,获得并返回真,否则立即返回假,实际上不再原地打转.
释放锁:
Spin_unlock(lock);
与spin_trylock或spin_lock配对使用。
一般这样使用:
Spinlock_t lock ;
Spin_lock_init(&lock);
Spin_lock(&lock);//获取自旋锁,包含临界区
.....//临界区
Spin_unlock(&lock); //解锁
使用自旋锁实际上是忙等锁,当锁不可用时,CPU一直循环执行测试并设置该锁直到可用而
取得该锁。此时CPU在等待自旋锁不做任何有用的工作,仅仅是等待。因此只有在
占用锁极短的情况下,使用自旋锁才是合理的,如果临界区有很大或者有共享设备的时候
,需要较长时间占用锁,会降低系统的性能。
自旋锁可能导致系统死锁,常见情况就是递归一个自旋锁,如果已经拥有某个自旋锁的
CPU想第二次获得这个自旋锁,则该CPU将死锁。如果进程获得自旋锁后再阻塞,也可能
导致死锁的发生。copy_from_user(),copy_to_user()和kmalloc()等函数都有可能引起阻塞。
因此自旋锁的占用期间不能调用这些函数。
读写自旋锁:是一种比自旋锁粒度更小的锁机制,它保留了自旋的概念,但是在写操作方面,
只能最多有一个写进程,在读操作方面,同事可以有多个读执行单元。当然,读和写也不能同事进行。
定义和初始化:
rwlock_t lock = RW_LOCK_LOCKED ; //静态初始化
rwloct_t lock ;
rwlock_init(&lock);
读锁定:
read_lock(rwlock_t *lock);
read_lock_irq(rwlock_t *lock);
read_lock_irqsave(rwlock_t *lock , unsigned long flags);
read_lock_bh(rwlock_t *lock);
读解锁:
read_unlock(rwlock_t *lock);
read_unlock_irq(rwlock_t *lock);
read_unlock_irqrestore(rwlock_t *lock , unsigned long flags);
read_unlock_bh(rwlock_t *lock);
......
linux内核中访问共享资源的更多相关文章
- Linux内核中锁机制之RCU、大内核锁
在上篇博文中笔者分析了关于完成量和互斥量的使用以及一些经典的问题,下面笔者将在本篇博文中重点分析有关RCU机制的相关内容以及介绍目前已被淘汰出内核的大内核锁(BKL).文章的最后对<大话Linu ...
- Linux内核中锁机制之信号量、读写信号量
在上一篇博文中笔者分析了关于内存屏障.读写自旋锁以及顺序锁的相关内容,本篇博文将着重讨论有关信号量.读写信号量的内容. 六.信号量 关于信号量的内容,实际上它是与自旋锁类似的概念,只有得到信号量的进程 ...
- 大话Linux内核中锁机制之RCU、大内核锁
大话Linux内核中锁机制之RCU.大内核锁 在上篇博文中笔者分析了关于完成量和互斥量的使用以及一些经典的问题,下面笔者将在本篇博文中重点分析有关RCU机制的相关内容以及介绍目前已被淘汰出内核的大内核 ...
- 大话Linux内核中锁机制之信号量、读写信号量
大话Linux内核中锁机制之信号量.读写信号量 在上一篇博文中笔者分析了关于内存屏障.读写自旋锁以及顺序锁的相关内容,本篇博文将着重讨论有关信号量.读写信号量的内容. 六.信号量 关于信号量的内容,实 ...
- Linux内核中的并发与竞态概述
1.前言 众所周知,Linux系统是一个多任务的操作系统,当多个任务同时访问同一片内存区域的时候,这些任务可能会相互覆盖内存中数据,从而造成内存中的数据混乱,问题严重的话,还可能会导致系统崩溃. 2. ...
- Linux 内核中的 Device Mapper 机制
本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...
- Linux内核中的GPIO系统之(3):pin controller driver代码分析
一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道,pin control subsystem也不例外,被它驱动的硬件叫做pin controller(一般ARM soc的datash ...
- Apparmor——Linux内核中的强制访问控制系统
AppArmor 因为最近在研究OJ(oline judge)后台的安全模块的实现,所以一直在研究Linux下沙箱的东西,同时发现了Apparmor可以提供访问控制. AppArmor(Appli ...
- KSM剖析——Linux 内核中的内存去耦合
简介: 作为一个系统管理程序(hypervisor),Linux® 有几个创新,2.6.32 内核中一个有趣的变化是 KSM(Kernel Samepage Merging) 允许这个系统管理程序通 ...
随机推荐
- java中抽象类的定义和使用
java虽然比较简单,但是细节的知识点还是很多的,现在,介绍一下抽象类的定义和实现基础. 指的是在类中定义方法,而不去实现它,而在它的子类中去具体实现,继承抽象类的子类必须实现父类的抽象方法,除非子类 ...
- 【编程练习】poj1111
Image Perimeters Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8632 Accepted: 5168 ...
- Android项目开发填坑记-Fragment的onAttach
背景 现在Android开发多使用一个Activity管理多个Fragment进行开发,不免需要两者相互传递数据,一般是给Fragment添加回调接口,让Activity继承并实现. 回调接口一般都写 ...
- Cocos2D瓦块地图高清屏(retina)显示比例问题的解决
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在Cocos2D的游戏编程里,常用到瓦块地图.而cocos2D ...
- android开源库发布到jcenter图文详解与填坑
相信很多人都用过开源项目,特别是android studio普及以后,使用开源库更方便简单.而如何上传开源库到jcenter供大家方便使用,虽然网上也有教程,但还是遇坑了,最后总结一下,希望可以帮助大 ...
- 【一天一道LeetCode】#290. Word Pattern
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- Sharepoint2013部署ADFS 报new-sptrustedIdentityTokenIssuer:the trust provider certificate already exist
在做sharepoint2013的adfs部署时,根据MSDN的步骤到新建身份验证程序时,powershell中报"ADFS new-sptrustedIdentityTokenIssuer ...
- Java正则表达式小记
http://blog.csdn.net/pipisorry/article/details/51059500 正则表达式的一般规则都一样,见[python正则表达式] java正则表达式中的特殊字符 ...
- (六十九)使用block进行消息传递
在两个类之间进行消息传递,一般通过代理或者block进行,代理写起来较为麻烦,block较为简单,但是block需要特别注意内存泄漏问题,注意self和block之间要为弱引用,下面介绍使用block ...
- 使用js动态添加组件
在文章开始之前,我想说两点 1 自己初学js,文章的内容在大神看来可能就是不值一提,但是谁都是从hello world来的,望高 手不吝指教# 2 我知道这个标题起的比较蛋疼,大家看图就能说明问题 ...