目录
 
1、自旋锁作用与基本使用方法?
与其他锁一样,自旋锁也用于保护临界区,但是自旋锁主要是用于在SMP上保护临界区。在SMP上,自旋锁最多只能被一个可执行线程持有,如果一个线程尝试获得一个被争用的自旋锁,该线程将一直旋转(while循环)直到锁可用;如果锁未被争用,请求锁的执行线程将立刻争用它,并继续执行。
 
LINUX下自旋锁的基本使用方法:
声明锁:
spinlock_t lock;
 
初始化:
lock = SPIN_LOCK_UNLOCKED;
     或者
spin_lock_init(&lock);
 
加锁有4个接口,3个会阻塞,1个不阻塞
spin_lock(&lock);//获取自旋锁
spin_lock_irq(&lock);//关中断,获取自旋锁,不建议使用
spin_lock_irqsave(&lock, flags);//关中断,保存中断状态,获取自旋锁
spin_trylock(&lock);//与spin_lock一样,但是获取不到的时候不阻塞,返回非0
 
对应的解锁接口有3个
spin_unlock(&lock);//spin_lock和spin_trylock都用该接口解锁
spin_unlock_irq(&lock);//不建议使用
spin_unlock_irqrestore(&lock, flags);
 
另外还提供了一个获取锁状态的接口:
spin_is_locked(&lock);//如果指定的锁被获取,返回非0,否则,返回0
 
2、在SMP和UP上的不同表现?
对于SMP,自旋锁将在禁止抢占后,while循环自旋直到锁可用;
对于UP,自旋锁的行为有点不一样,具体表现为:
  • 内核不支持抢占,则spin_lock是个空函数,spin_unlock也是空函数;
  • 内核支持抢占,则spin_lock关抢占,spin_unlock开抢占。
要分析SMP和UP的区别,还得先理解UP下内核支持抢占与否的区分。
在不支持抢占的时候,内核调度时机为:
  • 内核代码一直要执行到完成(返回用户空间);
  • 阻塞或主动调用schedule();
支持内核抢占的内核,则在以下情况会发生抢占:
  • 从中断处理程序回到内核空间且内核具有抢占性时;
  • 当内核代码再一次具有可抢占性时;(如时钟中断,发现进程时间片已经用完,则发生进程抢占)
  • 内核显式调用schedule();
  • 内核中的任务阻塞(同样导致schedule());

从以上区别可以看出,若是内核不支持抢占,只要临界区的代码不阻塞,就能保证原子性,所以spin_lock/spin_unlock是空函数。

而对于支持抢占的内核, spin_lock/spin_unlock自然只需要关闭/恢复抢占功能即可。
 
 
3、自旋锁与上下文
由于自旋锁不睡眠,既可以用于进程上下文,也可用于非进程上下文,这是它与信号量相比的一个优势。
正常来讲,如果自旋锁都是在进程上下文中使用,则建议使用spin_lock/spin_unlock。
若在中断处理例程中也要使用自旋锁,则所有争用同一个锁的地方应使用spin_lock_irqsave/spin_unlock_irqrestore。
若没有在中断而在下半部使用自旋锁,则所有急用同一个锁的地方可以使用spin_lock_bh/spin_unlock_bh,这对函数平时用得比较少。
注:自旋锁用在中断例程中,若是进程上下文中的内核代码使用spin_lock,则在临界区,可能发生中断 ,要么原子性被破坏(UP),要么造成死锁(SMP).
 
4、使用spin_lock()后为什么不能睡眠?
在UP下,正如前面所说,原子性得不到保证。
而在SMP下,则可能发生死锁:
假设有3个进程A,B,C,2个CPU称CPU0,CPU1.
CPU0上A进程获取自旋锁进入睡眠,调度了B进程,B进程将自旋; 
CPU1上调度了C进程也将自旋。
B等着A释放锁,A等着B释放CPU,自旋后的CPU不能发生调度,CPU0和CPU1将一直自旋下去,形成了死锁。
 
 
5、强调:锁什么?
使用锁的时候一定要对症下药,明确保护的是数据而不是代码,这是使用锁的正确思考方式。经常看别人代码的人应该会有所体会,针对代码加锁常常使代码难以理解,特别是复杂的程序,往往加锁没做好,引起竞争条件。
不防在使用锁的时候先思考一下自己要保护什么,然后给对应的锁取跟数据相关的名称。比如"int foo;spinlock_t foo_lock;"表示foo由foo_lock加锁;
 
6、参考
《Linux内核设计与实现》

LINUX内核笔记:自旋锁的更多相关文章

  1. [内核同步]自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析

    转自:http://blog.csdn.net/wh_19910525/article/details/11536279 自旋锁的初衷:在短期间内进行轻量级的锁定.一个被争用的自旋锁使得请求它的线程在 ...

  2. [内核同步]自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析【转】

    转自:https://www.cnblogs.com/x_wukong/p/8573602.html 转自;https://www.cnblogs.com/aaronLinux/p/5890924.h ...

  3. Linux内核笔记--内存管理之用户态进程内存分配

    内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...

  4. 【转载】linux内核笔记之进程地址空间

    原文:linux内核笔记之进程地址空间 进程的地址空间由允许进程使用的全部线性地址组成,在32位系统中为0~3GB,每个进程看到的线性地址集合是不同的. 内核通过线性区的资源(数据结构)来表示线性地址 ...

  5. 【转载】linux内核笔记之高端内存映射

    原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ...

  6. linux内核笔记-内核同步

    linux内核就相当于不断对请求进行响应的服务器,这些请求可能来自CPU,可能来自发出中断的外部设备.我们将内核看作两种请求的侍者. (1)老板提出请求,侍者如果空闲,为老板服务.(系统调用或异常) ...

  7. [转]透过 Linux 内核看无锁编程

    非阻塞型同步 (Non-blocking Synchronization) 简介 如何正确有效的保护共享数据是编写并行程序必须面临的一个难题,通常的手段就是同步.同步可分为阻塞型同步(Blocking ...

  8. Linux内核笔记:epoll实现原理(一)

    一.说明 针对的内核版本为4.4.10. 本文只是我自己看源码的简单笔记,如果想了解epoll的实现,强烈推荐下面的文章: The Implementation of epoll(1) The Imp ...

  9. Linux内核笔记--深入理解文件描述符

    内核版本:linux-2.6.11 文件描述符(file descriptor)在Linux编程里随处可见,设备读写.网络通信.进程通信,fd可谓是关键中的关键. 深入理解可以增加我们使用它的信心. ...

随机推荐

  1. python学习笔记3(元组、字典)

    Python中有三种内置的数据类型.dictionary(字典).List(列表)和tuple(元组). 元组(tuple) 只读列表(列表的值可以修改,元组的不可以) 元组与列表类似,不同之处在于元 ...

  2. IO流(三)__字节流 标准输入输出流 转换流

    一.字节流:FileInputStream 和FileOutputStream 基本操作和字符流类相同,没有flush,但是close还是要的 复制一个字节流文件 private static voi ...

  3. 8种效果实例-jQuery anoSlide 焦点图轮播

    anoslide是一款可调节效果至任意宽度大小,支持图文混合内容显示的图片轮播插件. 在线实例 单个 多个 动画延迟 自动播放 显示分页 显示标题 延迟加载 自适应高度 使用方法 <div cl ...

  4. Walkway.js – 用线条制作简约的 SVG 动画

    Walkway.js 是一个使用线条和路径元素组成 SVG 动画图像的简单方法.只需根据提供的配置对象创建一个新的 Walkway 实例就可以了.这种效果特别适合那些崇尚简约设计风格的网页.目前, W ...

  5. 2013年最新流行的响应式 WordPress 主题【上篇】

    WordPress 是最流行的内容管理系统,经历了多年的发展和演变.它的成功体现在庞大的社区,数百万的用户,设计师和开发者推动着 WordPress 往更高的层次发展. 海量的免费主题是 WordPr ...

  6. javascript中数组的常用方法

    数组的基本方法如下 1.concat() 2.join() 3.pop() 4.push() 5.reverse() 6.shift() 7.sort() 8.splice() 9.toString( ...

  7. ora-00119和ora-00132解决方案

    win7 64位    oracle 11g  先登录到sqlplus: sqlplus /nolog; 登录数据库: conn system/manager as sysdba; 然后启动数据库: ...

  8. ArcGisServer根据最大最小坐标换算瓦片行列号

    1.前言 在上一节中我们知道了屏幕上一像素等于实际中多少单位长度(米或经纬度)的换算方法,而知道这个原理后,接下来我们要怎么用它呢?它和我们前端显示地图有什么关联呢?这一节,我会尽量详细的将这两个问题 ...

  9. Android Activity和Fragment的转场动画

    Android Activity和Fragment的转场动画 Activity转场动画 Activity的转场动画是通过overridePendingTransition(int enterAnim, ...

  10. <转>iOS性能优化:Instruments使用实战

    最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instruments使用技巧 关于Instruments官方有一个很有 ...