您的位置 首页 新能源

你知道自旋锁和互斥锁差异?

你知道自旋锁和互斥锁区别?-POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API。线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用就是用Pthreads提供的锁机制(lock)来对多个线程之间共 享的临界区(Critical Section)进行保护(另一种常用的同步机制是barrier)。

POSIX threads(简称Pthreads)是在多核渠道上进行并行编程的一套常用的API。线程同步(Thread Synchronization)是并行编程中非常重要的通讯手法,其中最典型的运用便是用Pthreads供给的机制(lock)来对多个线程之间共 享的临界区(CriTIcal SecTIon)进行维护(另一种常用的同步机制是barrier)。

Pthreads供给了多种锁机制:
(1) Mutex(互斥量):pthread_mutex_***
(2) Spin lock(自旋锁):pthread_spin_***
(3) CondiTIon Variable(条件变量):pthread_con_***
(4) Read/Write lock(读写锁):pthread_rwlock_***

Pthreads供给的Mutex锁操作相关的API主要有:
pthread_mutex_lock (pthread_mutex_t *mutex);
pthread_mutex_trylock (pthread_mutex_t *mutex);
pthread_mutex_unlock (pthread_mutex_t *mutex);

Pthreads供给的与Spin Lock锁操作相关的API主要有:
pthread_spin_lock (pthread_spinlock_t *lock);
pthread_spin_trylock (pthread_spinlock_t *lock);
pthread_spin_unlock (pthread_spinlock_t *lock);

从 完成原理上来讲,Mutex归于sleep-waiTIng类型的锁。例如在一个双核的机器上有两个线程(线程A和线程B),它们别离运转在Core0和 Core1上。假定线程A想要经过pthread_mutex_lock操作去得到一个临界区的锁,而此刻这个锁正被线程B所持有,那么线程A就会被堵塞 (blocking),Core0 会在此刻进行上下文切换(Context Switch)将线程A置于等候行列中,此刻Core0就可以运转其他的使命(例如另一个线程C)而不用进行忙等候。而Spin lock则不然,它归于busy-waiting类型的锁,假如线程A是运用pthread_spin_lock操作去恳求锁,那么线程A就会一向在 Core0上进行忙等候并不断的进行锁恳求,直到得到这个锁停止。

所以,自旋锁一般用用多核的服务器。 

自旋锁(Spin lock)

自旋锁与互斥锁有点相似,仅仅自旋锁不会引起调用者睡觉,假如自旋锁现已被其他履行单元坚持,调用者就一向循环在那里看是 否该自旋锁的坚持者现已开释了锁,”自旋”一词便是因而而得名。其效果是为了处理某项资源的互斥运用。由于自旋锁不会引起调用者睡觉,所以自旋锁的功率远 高于互斥锁。尽管它的功率比互斥锁高,可是它也有些不足之处:
    1、自旋锁一向占用CPU,他在未取得锁的情况下,一向运转--自旋,所以占用着CPU,假如不能在很短的时 间内取得锁,这无疑会使CPU功率下降。
    2、在用自旋锁时有或许形成死锁,当递归调用时有或许形成死锁,调用有些其他函数也或许形成死锁,如 copy_to_user()、copy_from_user()、kmalloc()等。
因而咱们要稳重运用自旋锁,自旋锁只要在内核可抢占式或SMP的情况下才真实需求,在单CPU且不行抢占式的内核下,自旋锁的操作为空操作。自旋锁适用于锁运用者坚持锁时间比较短的情况下。
       自旋锁的用法如下:
   首要界说:spinlock_t x;
 然后初始化:spin_lock_init(spinlock_t *x);   //自旋锁在真实运用前必须先初始化
 在2.6.11内核中将界说和初始化合并为一个宏:DEFINE_SPINLOCK(x)
    
  取得自旋锁:spin_lock(x);   //只要在取得锁的情况下才回来,不然一向“自旋”
                           spin_trylock(x);  //如当即取得锁则回来真,不然当即回来假
      开释锁:spin_unlock(x);
    
结合以上有以下代码段:

    spinlock_t lock;        //界说一个自旋锁
    spin_lock_init(&lock);
    spin_lock(&lock);    
    …….        //临界区
    spin_unlock(&lock);   //开释锁
    
    还有一些其他用法:
spin_is_locked(x)
    //  该宏用于判别自旋锁x是否现已被某履行单元坚持(即被锁),假如是,   回来真,不然回来假。
spin_unlock_wait(x)
    //  该宏用于等候自旋锁x变得没有被任何履行单元坚持,假如没有任何履行单元坚持该自旋锁,该宏当即回来,否
    //将循环    在那里,直到该自旋锁被坚持者开释。

spin_lock_irqsave(lock, flags)
    //  该宏取得自旋锁的一起把标志寄存器的值保存到变量flags中并失效本地中//断。适当于:spin_lock()+local_irq_save()
spin_unlock_irqrestore(lock, flags)
    //  该宏开释自旋锁lock的一起,也康复标志寄存器的值为变量flags保存的//值。它与spin_lock_irqsave配对运用。
    //适当于:spin_unlock()+local_irq_restore()

spin_lock_irq(lock)
    //该宏相似于spin_lock_irqsave,仅仅该宏不保存标志寄存器的值。适当         //于:spin_lock()+local_irq_disable()
spin_unlock_irq(lock)
    //该宏开释自旋锁lock的一起,也使能本地中止。它与spin_lock_irq配对运用。适当于: spin_unlock()+local_irq+enable()

spin_lock_bh(lock)
    //  该宏在得到自旋锁的一起失效本地软中止。适当于:  //spin_lock()+local_bh_disable()
spin_unlock_bh(lock)
      //该宏开释自旋锁lock的一起,也使能本地的软中止。它与spin_lock_bh配对//运用。适当于:spin_unlock()+local_bh_enable()

spin_trylock_irqsave(lock, flags)
    //该宏假如取得自旋锁lock,它也将保存标志寄存器的值到变量flags中,而且失//效本地中止,假如没有取得锁,它什么也不做。因而假如可以当即 取得锁,它等//同于spin_lock_irqsave,假如不能取得锁,它同等于spin_trylock。假如该宏//取得自旋锁lock,那需求 运用spin_unlock_irqrestore来开释。

spin_trylock_irq(lock)
    //该宏相似于spin_trylock_irqsave,仅仅该宏不保存标志寄存器。假如该宏取得自旋锁lock,需求运用spin_unlock_irq来开释。
spin_trylock_bh(lock)
    //  该宏假如取得了自旋锁,它也将失效本地软中止。假如得不到锁,它什么//也不做。因而,假如得到了锁,它同等于spin_lock_bh,假如得 不到锁,它同等//于spin_trylock。假如该宏得到了自旋锁,需求运用spin_unlock_bh来开释。
spin_can_lock(lock)
    //  该宏用于判别自旋锁lock是否可以被锁,它实践是spin_is_locked取反。//假如lock没有被锁,它回来真,不然,回来 假。该宏在2.6.11中第一次被界说,在//从前的内核中并没有该宏。

 

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/xinnengyuan/90240.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部