zoukankan      html  css  js  c++  java
  • 互斥锁,自旋锁,读写锁与原子操作

    互斥锁:用在执行长的代码块效率较高,如果只是执行一条少的指令,速度不如自旋锁和原子锁。互斥锁只有两种状态:锁住和未锁住

    读写锁:非常适合于对数据结构读的次数远远大于写的情况。同时可以有多个线程获得读锁,同时只允许有一个线程获得写锁。其他线程在等待锁的时候同样会进入睡眠。读写锁在互斥锁的基础上,允许多个线程“读”,在某些场景下能提高性能。

    自旋锁:如果被锁住,其他线程获取锁就会空转等待,消耗CPU资源,不会去休眠。

    原子操作:操作本身就具有原子性,不可拆分

    自旋锁(spin lock)与互斥量(mutex)的比较

    自旋锁是一种非阻塞锁,也就是说,如果某线程需要获取自旋锁,但该锁已经被其他线程占用时,该线程不会被挂起,而是在不断的消耗CPU的时间,不停的试图获取自旋锁。

    互斥量是阻塞锁,当某线程无法获取互斥量时,该线程会被直接挂起,该线程不再消耗CPU时间,当其他线程释放互斥量后,操作系统会激活那个被挂起的线程,让其投入运行。

     

    两种锁适用于不同场景:

    如果是多核处理器如果预计线程等待锁的时间很短,短到比线程两次上下文切换时间要少的情况下,使用自旋锁是划算的

    如果是多核处理器如果预计线程等待锁的时间较长,至少比两次线程上下文切换的时间要长,建议使用互斥量

    如果是单核处理器,一般建议不要使用自旋锁。因为,在同一时间只有一个线程是处在运行状态,那如果运行线程发现无法获取锁,只能等待解锁,但因为自身不挂起,所以那个获取到锁的线程没有办法进入运行状态,只能等到运行线程把操作系统分给它的时间片用完,才能有机会被调度。这种情况下使用自旋锁的代价很高。

    如果加锁的代码经常被调用,但竞争情况很少发生时,应该优先考虑使用自旋锁,自旋锁的开销比较小,互斥量的开销较大。

     无锁数据结构:CAS(compare and swap)

    CAS算法的过程它包含三个参数CAS(V,E,N):
    V表示要更新的变量,E表示预期值,N表示新值。
    仅当V值等于E值时,才会将V的值设为N,
    如果V值和E值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。
    最后,CAS返回当前V的真实值。

    悲观锁:

    乐观锁:

  • 相关阅读:
    hash和history的区别帮助向我一样迷的人弄明白,history和hash
    调用谷歌浏览器的打印所遇到的困难,回流重绘
    webpack简单搭建基础感悟
    linux
    介绍一下call,apply,bind方法实现,源于MDN中的bind
    二进制流转base64加快速度
    手写一个instanceof
    青蛙跳台阶问题
    Django中vue的使用
    pip install 出现 timeout 时的两个临时解决办法
  • 原文地址:https://www.cnblogs.com/Arnold-Zhang/p/13334200.html
Copyright © 2011-2022 走看看