`
gstarwd
  • 浏览: 1488101 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

信号量和自旋锁

阅读更多

内核同步措施

    为了避免并发,防止竞争。内核提供了一组同步方法来提供对共享数据的保护。 我们的重点不是介绍这些方法的详细用法,而是强调为什么使用这些方法和它们之间的差别。
    Linux 使用的同步机制可以说从2.0到2.6以来不断发展完善。从最初的原子操作,到后来的信号量,从大内核锁到今天的自旋锁。这些同步机制的发展伴随 Linux从单处理器到对称多处理器的过度;伴随着从非抢占内核到抢占内核的过度。锁机制越来越有效,也越来越复杂。
    目前来说内核中原子操作多用来做计数使用,其它情况最常用的是两种锁以及它们的变种:一个是自旋锁,另一个是信号量。我们下面就来着重介绍一下这两种锁机制。


自旋锁
------------------------------------------------------
    自旋锁是专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断处理等部分(对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,不需要自旋锁)。
    自旋锁最多只能被一个内核任务持有,如果一个内核任务试图请求一个已被争用(已经被持有)的自旋锁,那么这个任务就会一直进行忙循环——旋转——等待锁重新可用。
要是锁未被争用,请求它的内核任务便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个的内核任务同时进入临界区,因此这种锁可有效地避免多处理器上并发运行的内核任务竞争共享资源。
    事实上,自旋锁的初衷就是:在短期间内进行轻量级的锁定。一个被争用的自旋锁使得请求它的线程在等待锁重新可用的期间进行自旋(特别浪费处理器时间),所以自旋锁不应该被持有时间过长。如果需要长时间锁定的话, 最好使用信号量。
自旋锁的基本形式如下:
    spin_lock(&mr_lock);
    //临界区
    spin_unlock(&mr_lock);

    因为自旋锁在同一时刻只能被最多一个内核任务持有,所以一个时刻只有一个线程允许存在于临界区中。这点很好地满足了对称多处理机器需要的锁定服务。在单处 理器上,自旋锁仅仅当作一个设置内核抢占的开关。如果内核抢占也不存在,那么自旋锁会在编译时被完全剔除出内核。
    简单的说,自旋锁在内核中主要用来防止多处理器中并发访问临界区,防止内核抢占造成的竞争。 另外自旋锁不允许任务睡眠(持有自旋锁的任务睡眠会造成自死锁——因为睡眠有可能造成持有锁的内核任务被重新调度,而再次申请自己已持有的锁),它能够在中断上下文中使用
    死锁:假设有一个或多个内核任务和一个或多个资源,每个内核都在等待其中的一个资源,但所有的资源都已经被占用了。这便会发生所有内核任务都在相互等待, 但它们永远不会释放已经占有的资源,于是任何内核任务都无法获得所需要的资源,无法继续运行,这便意味着死锁发生了。自死琐是说自己占有了某个资源,然后 自己又申请自己已占有的资源,显然不可能再获得该资源,因此就自缚手脚了。


信号量
------------------------------------------------------
    Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行 其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。
    信号量的睡眠特性,使得信号量适用于锁会被长时间持有的情况;只能在进程上下文中使用,因为中断上下文中是不能被调度的;另外当代码持有信号量时,不可以再持有自旋锁。

信号量基本使用形式为:
static DECLARE_MUTEX(mr_sem);//声明互斥信号量
if(down_interruptible(&mr_sem))
    //可被中断的睡眠,当信号来到,睡眠的任务被唤醒
    //临界区
up(&mr_sem);


信号量和自旋锁区别
------------------------------------------------------
    虽然听起来两者之间的使用条件复杂,其实在实际使用中信号量和自旋锁并不易混淆。注意以下原则:
    如果代码需要睡眠——这往往是发生在和用户空间同步时——使用信号量是唯一的选择。由于不受睡眠的限制,使用信号量通常来说更加简单一些。如果需要在自旋 锁和信号量中作选择,应该取决于锁被持有的时间长短。理想情况是所有的锁都应该尽可能短的被持有,但是如果锁的持有时间较长的话,使用信号量是更好的选 择。另外,信号量不同于自旋锁,它不会关闭内核抢占,所以持有信号量的代码可以被抢占。这意味者信号量不会对影响调度反应时间带来负面影响。


自旋锁对信号量
------------------------------------------------------
需求                     建议的加锁方法

低开销加锁               优先使用自旋锁
短期锁定                 优先使用自旋锁
长期加锁                 优先使用信号量
中断上下文中加锁          使用自旋锁
持有锁是需要睡眠、调度     使用信号量

分享到:
评论

相关推荐

    信号量与自旋锁

    信号量与自旋锁

    原子操作、信号量、读写信号量和自旋锁的API

    原子操作、信号量、读写信号量和自旋锁的API.希望能帮助大家

    信号量、互斥体和自旋锁的区别

    本文章是关于信号量、互斥体和自旋锁的区别。

    华为内部招聘面试题

    华为招聘面试题,内部流传出来的,想进华为的可以参考下

    linux 自旋锁讨论记录

    linux 自旋锁讨论记录,自旋锁与信号量有哪些差别,这里给出答案

    论文研究-面向流体系的细粒度异步访存调度.pdf

    针对异步访存调度机制...该机制引入信号量和自旋锁,由异构核间协作运作,以实现对流级调度的局部加速。通过在一组测试程序集以及在对应平台上进行的实验,评估了引入该机制的加速效果,并分析了影响其性能的各种因素。

    linux写优先的读写锁设计

    在linux下有两种实现数据互斥的基本机制,包括了信号量,自旋锁。这里要说的读写锁是自旋锁的一个变种

    C++ 互斥锁源码

    ConsoleApp_Mutex,C++互斥锁源码cpp,可在VC++6.0或VS下直接编译运行,演示结果,控制台程序,ConsoleApp_Mutex,C++互斥锁源码cpp,可在VC++6.0或VS下直接编译运行,演示结果,控制台程序,

    定向直接检测实验确定暗物质自旋

    为了进行比较,对于质量为100 GeV的WIMP和WIMP氟散射截面为0.25 pb的CF4检测器,在30托的压力下工作,预期暴露约26,000立方米检测器天,预计会有约100个信号事件。 可比的曝光量需要一组立方米时间投影室探测器。

    嵌入式系统/ARM技术中的spinlock与linux内核调度的关系

    作者:刘洪涛,华清远见嵌入式培训中心高级讲师,ARM公司... 这里也介绍下信号量的概念,因为它的用法和自旋锁有相似的地方。  Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量

    C语言实现基于Risc-V 的操作系统内核模拟设计与实现源代码,一个运行在RISC-V架构处理器上的玩具嵌入式操作系统

    完成了操作系统的引导、UART 串口驱动、中断管理、动态内存管理、多任务调度、自旋锁、信号量、FAT32 文件系统内核模块,并基于本课题的操作系统内核模块完成了一些用户态应用程序,包括链表数据结构、命令式文件...

    TauSpinner在LHC的$ Z $,$ W $和$ H $衰变中研究$ \ tau $ -Lepton极化和自旋相关性的应用

    t轻子的自旋表示一个有趣的现象学量,可以用于从背景中分离信号,以寻找新物理过程或测量衰减到\的新粒子的性质。 在蒙特卡洛模拟中正确处理旋转效应对理解检测器的接受度以及测量偏振度和旋转相关性很重要。 {\ sf...

    Linux下的“锁”事儿

    比较经典的有原子操作、spin_lock(自旋锁)、mutex(互斥锁)、semaphore(信号量)等。  原子操作  原子操作,也是数据库事务的一大特性。是该操作绝不会在执行完之前被任何任务或者事件终止,要不全部执行,...

    嵌入式Linux设备驱动开发视频教程

    教程描述:介绍Linux设备驱动开发理论、框架与实例,以Linux2.6版本内核为蓝本,详细介绍自旋锁、信号量、完成量、中断顶/底半部、定时器、内存和I/0映射以及异步通知、阻塞I/0、非阻塞I/0等Linux设备驱动理论;...

    Linux内核源码深度解析与开发实战视频.zip

    19:可睡眠锁:信号量semaphore_rec 20:可睡眠锁:读写信号量rwsem_rec 21:可睡眠锁:完成变量completion_rec 22:可睡眠锁:SRCUsleepable_read-copy-update_rec 23:原子操作_rec 24:内存屏障_rec ...........

    Linux设备驱动并发控制介绍

    在驱动程序中,当多个线程同时访问相同的资源时,可能会引发\"竞态\",因此我们必须对共享资源进行并发控制。Linux内核中解决并发控制的最常用方法是自旋锁与信号量...本文详细介绍了自旋锁与信号量的特点和实现方法。

    Linux内核的同步机制

    关于Linux内核的同步机制,自旋锁,信号量等

    宋宝华 基于最新的Linux4.0内核 文字版带书签

    本书介绍了Linux设备驱动开发理论、框架与实例,详细说明了自旋锁、信号量、完成量、中断顶/底半部、定时器、内存和I/O映射以及异步通知、阻塞I/O、非阻塞I/O等Linux设备驱动理论,以及字符设备、块设备、tty设备、I2...

    疯狂内核之——进程管理子系统

    4.9.1 获取和释放信号量 221 4.9.2 读/写信号量 224 4.9.3 补充信号量 225 4.10 禁止本地中断 226 4.10.1 禁止本地中断 227 4.10.2 禁止下半部(可延迟函数) 229 4.11 一些避免竞争条件的实例 231 4.11.1 引用...

    linux设备驱动详(第二版).part1

    本书是一本介绍Linux设备驱动开发理论、框架与实例的书,本书以Linux 2.6版本内核为蓝本,详细介绍自旋锁、信号量、完成量、中断顶/底半部、定时器、内存和I/O映射以及异步通知、阻塞I/O、非阻塞I/O等Linux设备驱动...

Global site tag (gtag.js) - Google Analytics