精华内容
下载资源
问答
  • 自旋锁(Spin lock)自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。...

    自旋锁(Spin lock)

    自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。其作用是为了解决某项资源的互斥使用。因为自旋锁不会引起调用者睡眠,所以自旋锁的效率远 高于互斥锁。虽然它的效率比互斥锁高,但是它也有些不足之处:
        1、自旋锁一直占用CPU,他在未获得锁的情况下,一直运行--自旋,所以占用着CPU,如果不能在很短的时 间内获得锁,这无疑会使CPU效率降低。
        2、在用自旋锁时有可能造成死锁,当递归调用时有可能造成死锁,调用有些其他函数也可能造成死锁,如 copy_to_user()、copy_from_user()、kmalloc()等。

    因此我们要慎重使用自旋锁,自旋锁只有在内核可抢占式或SMP的情况下才真正需要,在单CPU且不可抢占式的内核下,自旋锁的操作为空操作。自旋锁适用于锁使用者保持锁时间比较短的情况下。

    两种锁的加锁原理

    互斥锁:线程会从sleep(加锁)——>running(解锁),过程中有上下文的切换,cpu的抢占,信号的发送等开销。

    自旋锁:线程一直是running(加锁——>解锁),死循环检测锁的标志位,机制不复杂。


    互斥锁属于sleep-waiting类型的锁。例如在一个双核的机器上有两个线程(线程A和线程B),它们分别运行在Core0和 Core1上。假设线程A想要通过pthread_mutex_lock操作去得到一个临界区的锁,而此时这个锁正被线程B所持有,那么线程A就会被阻塞 (blocking),Core0 会在此时进行上下文切换(Context Switch)将线程A置于等待队列中,此时Core0就可以运行其他的任务(例如另一个线程C)而不必进行忙等待。而自旋锁则不然,它属于busy-waiting类型的锁,如果线程A是使用pthread_spin_lock操作去请求锁,那么线程A就会一直在 Core0上进行忙等待并不停的进行锁请求,直到得到这个锁为止。

    两种锁的区别

    互斥锁的起始原始开销要高于自旋锁,但是基本是一劳永逸,临界区持锁时间的大小并不会对互斥锁的开销造成影响,而自旋锁是死循环检测,加锁全程消耗cpu,起始开销虽然低于互斥锁,但是随着持锁时间,加锁的开销是线性增长。

    两种锁的应用

    互斥锁用于临界区持锁时间比较长的操作,比如下面这些情况都可以考虑

    1 临界区有IO操作

    2 临界区代码复杂或者循环量大

    3 临界区竞争非常激烈

    4 单核处理器

    至于自旋锁就主要用在临界区持锁时间非常短且CPU资源不紧张的情况下,自旋锁一般用于多核的服务器。


    展开全文
  • POSIX threads(简称Pthreads)是在多核平台上进行并行编程...线程同步(Thread Synchronization)是并行编程中非常重要通讯手段,其中最典型应用就是用Pthreads提供的锁机制(lock)来对多个线程之间共 享...

    http://blog.csdn.net/kyokowl/article/details/6294341

     

    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中第一次被定义,在//先前的内核中并没有该宏。



     

    转载于:https://www.cnblogs.com/zlcxbb/p/6432633.html

    展开全文
  • 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。其作用是为了解决...

    自旋锁(Spin lock)

    自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。其作用是为了解决某项资源的互斥使用。因为自旋锁不会引起调用者睡眠,所以自旋锁的效率远高于互斥锁。虽然它的效率比互斥锁高,但是它也有些不足之处:

    1、自旋锁一直占用CPU,他在未获得锁的情况下,一直运行--自旋,所以占用着CPU,如果不能在很短的时 间内获得锁,这无疑会使CPU效率降低。

    2、在用自旋锁时有可能造成死锁,当递归调用时有可能造成死锁,调用有些其他函数也可能造成死锁,如 copy_to_user()copy_from_user()kmalloc()等。

    因此我们要慎重使用自旋锁,自旋锁只有在内核可抢占式或SMP的情况下才真正需要,在单CPU且不可抢占式的内核下,自旋锁的操作为空操作。自旋锁适用于锁使用者保持锁时间比较短的情况下。

    两种锁的加锁原理

    互斥锁:线程会从sleep(加锁)——>running(解锁),过程中有上下文的切换,cpu的抢占,信号的发送等开销。

    自旋锁:线程一直是running(加锁——>解锁),死循环检测锁的标志位,机制不复杂。

    互斥锁属于sleep-waiting类型的锁。例如在一个双核的机器上有两个线程(线程A和线程B),它们分别运行在Core0Core1上。假设线程A想要通过pthread_mutex_lock操作去得到一个临界区的锁,而此时这个锁正被线程B所持有,那么线程A就会被阻塞 (blocking),Core0 会在此时进行上下文切换(Context Switch)将线程A置于等待队列中,此时Core0就可以运行其他的任务(例如另一个线程C)而不必进行忙等待。而自旋锁则不然,它属于busy-waiting类型的锁,如果线程A是使用pthread_spin_lock操作去请求锁,那么线程A就会一直在 Core0上进行忙等待并不停的进行锁请求,直到得到这个锁为止。

    两种锁的区别

    互斥锁的起始原始开销要高于自旋锁,但是基本是一劳永逸,临界区持锁时间的大小并不会对互斥锁的开销造成影响,而自旋锁是死循环检测,加锁全程消耗cpu,起始开销虽然低于互斥锁,但是随着持锁时间,加锁的开销是线性增长。

    两种锁的应用

    互斥锁用于临界区持锁时间比较长的操作,比如下面这些情况都可以考虑

    1. 临界区有IO操作

    2. 临界区代码复杂或者循环量大

    3. 临界区竞争非常激烈

    4. 单核处理器

    至于自旋锁就主要用在临界区持锁时间非常短且CPU资源不紧张的情况下,自旋锁一般用于多核的服务器。

    展开全文
  • 锁是为了解决某种资源...自旋锁与互斥锁的区别在于:自旋锁在执行单元在获取锁之前,如果发现有其他执行单元正在占用锁,则会不停的循环判断锁状态,直到锁被释放,期间并不会阻塞自己。由于在等待时不断的"自旋",...

    锁是为了解决某种资源(又称为临界资源)互斥使用提出的一种机制。常用的有互斥锁、自旋锁和读写锁。

    自旋锁和互斥锁功在使用时差不多,每一时刻只能有一个执行单元占有锁,而占有锁的单元才能获得临界资源的使用权,从而达到了互斥的目的。

    自旋锁与互斥锁的区别在于:自旋锁在执行单元在获取锁之前,如果发现有其他执行单元正在占用锁,则会不停的循环判断锁状态,直到锁被释放,期间并不会阻塞自己。由于在等待时不断的"自旋",这也是它为什么叫做自旋锁。所以自旋锁使用时,是非常消耗CPU资源的。

    而互斥锁在执行单元等待锁释放时,会把自己阻塞并放入到队列中。当锁被释放时,会唤醒队列上执行单元把其放入就绪队列中,并由调度算法进行调度并执行。所以互斥锁使用时会有线程的上下文切换,这可能是非常耗时的一个操作,但是等待锁期间不会浪费CPU资源。

    两种锁适用于不同场景:

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

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

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

    大部分操作系统并不严格区分互斥锁和自旋锁。 实际上, 绝大部分现代的操作系统采用的是混合型互斥锁(hybrid mutexes)和混合型自旋锁(hybrid spinlocks)。

    混合型互斥锁, 在多核系统上起初表现的像自旋锁一样, 如果一个线程不能获取互斥锁, 它不会马上被切换为休眠状态,因为互斥量可能很快就被解锁, 所以这种机制会表现的像自旋锁一样。 只有在一段时间以后(或者尝试一定次数,或者其他指标)还不能获取锁, 它就会被切换为休眠状态。 。

    混合型自旋锁,起初表现的和正常自旋锁一样,但是为了避免浪费大量的CPU时间, 会有一个折中的策略。 这种机制不会把线程切换到休眠态(既然想要使用自旋锁,那么你并不希望这种情况发生), 也许会决定放弃这个线程的执行(马上放弃或者等一段时间)并允许其他线程运行, 这样提高了自旋锁被解锁的可能性(大多数情况,线程之间的切换操作比使线程休眠而后唤醒它要昂贵,尽管那不是很明显)。

    读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。在读写锁保持期间也是抢占失效的。

    如果读写锁当前没有读者,也没有写者,那么写者可以立刻获得读写锁,否则它必须自旋在那里,直到没有任何写者或读者。如果读写锁没有写者,那么读者可以立即获得该读写锁,否则读者必须自旋在那里,直到写者释放该读写锁。

    展开全文
  • 互斥锁与自旋锁:谁更轻松自如? 最底层的两种就是会「互斥锁和自旋锁」,有很多高级的锁都是基于它们实现的,你可以认为它们是各种锁的地基,所以我们必须清楚它俩之间的区别和应用。 加锁的目的就是保证共享资源...
  • 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。其作用是为了解决某项资源的...
  • 互斥锁与自旋锁:谁更轻松自如读写锁:读和写还有优先级区分?乐观锁与悲观锁:做事心态有何不同?总结 以下文章来源于wechat公众号小林coding ,作者小林coding 互斥锁与自旋锁:谁更轻松自如 最底层两种就是...
  • 互斥锁自旋锁、条件变量、信号量的区别: (1)首先,互斥锁必须总是由给它上锁的线程解锁。信号量没有这种限制:一个线程可以等待某个给定信号量,而另一个线程可以挂出该信号量。 (2)其次,一个信号量有一个...
  • 什么是同步?什么是互斥? 什么是异步执行?为什么需要代码异步执行? 什么是信号量?什么是互斥锁?什么是自旋锁? 互斥锁和信号量的区别是什么?互斥锁自旋锁的区别是什么?
  • 2.自旋锁的使用场景 3.三种操作的使用场景与区别 【技术分享篇】epoll的具体实现epoll线程安全,互斥锁,自旋锁,CAS,原子操作 更多Linux服务器开发高阶完整视频分享,点击链接即可观看:...
  • 锁是为了解决某种资源(又称为临界资源)互斥使用提出的一种机制。常用的有互斥锁自旋锁和读写锁。...自旋锁与互斥锁的区别在于:自旋锁在执行单元在获取锁之前,如果发现有其他执行单元正在占用锁,则会...
  • 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。其作用是为了解决...
  • 1.实现方式上的区别互斥锁是基于自旋锁实现的,所以自旋锁相较于互斥锁更加底层。 2.开销上的区别:获取不到互斥锁时会发生上下文切换并休眠,而自旋锁则“自旋”在原地直到被获取。 3.使用场景的区别互斥锁...
  • pthread的互斥量和自旋锁

    千次阅读 2016-07-29 20:53:32
    一、自旋锁与互斥的区别 在多处理器环境中,自旋锁最多只能被一个可执行线程持有。如果一个可执行线程试图获得一个被争用(已经被持有的)自旋锁,那么该线程就会一直进行忙等待,自旋,也就是空转,等待锁重新可用...
  • POSIX threads(简称Pthreads)是在多核平台上进行并行编程一套API。线程同步是并行编程中非常重要通讯手段,其中最典型应用就是用Pthreads...Pthreads提供了多种机制:Mutex(互斥量):pthread_mutex_tSpin...
  • 同步与互斥经常放在一起讲,是因为它们之间关系很大,“互斥”操作可以用“同步”来实现。我“等”你用完厕所,我再用厕所。这不就是用“同步”来实现“互斥”吗?伪代码如下: void 抢厕所(void) { if(有人在...
  • 自旋锁 互斥锁 读写锁 递归锁 互斥锁(mutexlock): 最常使用于线程同步锁;标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁;临界区和互斥量都可用来实现此锁,通常...
  • 自旋锁是一种互斥锁的实现方式而已,相比一般的互斥锁会在等待期间放弃cpu,自旋锁(spinlock)则是不断循环并测试锁的状态,这样就一直占着cpu。 互斥锁:用于保护临界区,确保同一时间只有一个线程访问数据。对...
  • 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁,”自旋”一词就是因此而得名。其作用是为了解决某项资源...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 123
精华内容 49
关键字:

互斥锁与自旋锁的区别