美文网首页
信号量、互斥体和自旋锁

信号量、互斥体和自旋锁

作者: hswwjp | 来源:发表于2018-12-24 10:37 被阅读12次

互斥体

       互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex))。互斥体禁止多个线程同时进入受保护的代码“临界区”(critical section)。因此,在任意时刻,只有一个线程被允许进入这样的代码保护区。
  任何线程在进入临界区之前,必须获取(acquire)与此区域相关联的互斥体的所有权。如果已有另一线程拥有了临界区的互斥体,其他线程就不能再进入其中。这些线程必须等待,直到当前的属主线程释放(release)该互斥体。
  什么时候需要使用互斥体呢?\color{red}{互斥体用于保护共享的易变代码,也就是,全局或静态数据。}这样的数据必须通过互斥体进行保护,以防止它们在多个线程同时访问时损坏。


自旋锁

自旋锁它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看该自旋锁的保持者是否已经释放了锁,"自旋"一词就是因此而得名。

自旋锁原理

自旋锁适用情况

自旋锁比较适用于锁使用者保持锁时间比较短的情况。正是由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠是非常必要的,自旋锁的效率远高于互斥锁。信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用,而自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用。如果被保护的共享资源只在进程上下文访问,使用信号量保护该共享资源非常合适,如果对共享资源的访问时间非常短,自旋锁也可以。但是如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),就必须使用自旋锁。自旋锁保持期间是抢占失效的,而信号量和读写信号量保持期间是可以被抢占的。自旋锁只有在内核可抢占或SMP(多处理器)的情况下才真正需要,在单CPU且不可抢占的内核下,自旋锁的所有操作都是空操作。另外格外注意一点:自旋锁不能递归使用。


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

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

信号量/互斥体允许进程睡眠属于睡眠锁,自旋锁则不允许调用者睡眠,而是让其循环等待,所以有以下区别应用

  1. 信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因而自旋锁适合于保持时间非常短的情况
  2. 自旋锁可以用于中断,不能用于进程上下文(会引起死锁)。而信号量不允许使用在中断中,而可以用于进程上下文
  3. 自旋锁保持期间是抢占失效的,自旋锁被持有时,内核不能被抢占,而信号量和读写信号量保持期间是可以被抢占的

另外需要注意的是

  1. 信号量锁保护的临界区可包含可能引起阻塞的代码,而自旋锁则绝对要避免用来保护包含这样代码的临界区,因为阻塞意味着要进行进程的切换,如果进程被切换出去后,另一进程企图获取本自旋锁,死锁就会发生。
  2. 在你占用信号量的同时不能占用自旋锁,因为在你等待信号量时可能会睡眠,而在持有自旋锁时是不允许睡眠的。
信号量和互斥体之间的区别

概念上的区别:
信号量:是进程间(线程间)同步用的,一个进程(线程)完成了某一个动作就通过信号量告诉别的进程(线程),别的进程(线程)再进行某些动作。有二值和多值信号量之分。
互斥锁:是线程间互斥用的,一个线程占用了某一个共享资源,那么别的线程就无法访问,直到这个线程离开,其他的线程才开始可以使用这个共享资源。可以把互斥锁看成二值信号量。

上锁时:
信号量: 只要信号量的 value大于0,其他线程就可以 sem_wait成功,成功后信号量的 value减一。若 value值不大于0,则 sem_wait阻塞,直到 sem_post释放后 value值加一。一句话,信号量的 value >= 0。
互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源。如果没有锁,获得资源成功,否则进行阻塞等待资源可用。一句话,线程互斥锁的 vlaue可以为负数。

使用场所:
信号量主要适用于进程间通信,当然,也可用于线程间通信。而互斥锁只能用于线程间通信。

参考链接:
https://www.cnblogs.com/biyeymyhjob/archive/2012/07/21/2602015.html

相关文章

  • Linux内核设计与实现——内核同步方法

    主要内容 原子操作 自旋锁 读写自旋锁 信号量 读写信号量 互斥锁 完成变量 大内核锁 顺序锁 禁止抢占 顺序和屏...

  • iOS 多线程(一)-锁

    1.概述 1.1 类型 自旋锁 OSSpinLock 信号量 dispatch_semaphore 互斥锁 ...

  • iOS锁

    锁的作用:保证线程安全。锁的分类:互斥锁,自旋锁,其它比如条件锁,递归锁,信号量都是上层的封装和实现。 互斥锁 防...

  • 竞态与同步(1)

    内核里处理的竞态主要通过以下方法处理: 信号量(互斥量)、自旋锁、读写信号量、读写自旋锁、等待队列、完成量。 信号...

  • 信号量、互斥体和自旋锁

    互斥体 互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mute...

  • 多线程--锁

    本文主要介绍: 互斥锁 递归锁 读写锁 自旋锁 分布锁 条件变量 信号量 栅栏 一些常用锁的性能。 1. 互斥锁(...

  • 2020-07-24

    锁 OSSpinLock 自旋锁 实现机制:忙等 操作重点:原子操作1.自旋锁2.互斥锁3.读写锁4.信号量5.条...

  • Linux下的线程同步方法

    Something about sync 目前接触到的同步机制有如下: 互斥锁 条件变量 读写锁 信号量 自旋锁 ...

  • CLH并发队列

    1 什么是自旋锁和互斥锁? 由于CLH锁是一种自旋锁,那么我们先来看看自旋锁是什么? 自旋锁说白了也是一种互斥锁,...

  • iOS面试题与核心基础之线程同步(锁,串行队列,信号量,@syn

    锁 iOS多线程锁有两类 自旋锁 和 互斥锁自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。资源已...

网友评论

      本文标题:信号量、互斥体和自旋锁

      本文链接:https://www.haomeiwen.com/subject/bqgokqtx.html