自旋锁和互斥锁的区别

POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套API。线程同步是并行编程中很是重要的通信手段,其中最典型的应用就是用编程

Pthreads提供的锁机制(lock)来对多个线程之间的共享临界区(Critical Section)进行保护(另外一种经常使用的同步机制是barrier)。函数

Pthreads提供了多种锁机制:线程

  • Mutex(互斥量):pthread_mutex_t
  • Spin lock(自旋锁): pthread_spin_t
  • Condition Variable(条件变量): pthread_cond_t
  • Read/Write lock(读写锁):pthread_rwlock_t

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就会被阻塞,资源

Core0会在此时进行上下文切换(Context Switch)将线程A置于等待队列中,此时Core0就能够运行其它的任务而没必要进行忙等待。而Spin lock同步

则否则,它属于busy-waiting类型的锁,若是线程A是使用pthread_spin_lock操做去请求锁,那么线程A就会一直在Core0上进行忙等待并不停的进行锁请求,直到获得这个锁为止。it

自旋锁(Spin lock)io

自旋锁与互斥锁有点相似,只是自旋锁不会引发调用者睡眠,若是自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,“自旋锁”的做用thread

是为了解决某项资源的互斥使用。由于自旋锁不会引发调用者睡眠,因此自旋锁的效率远高于互斥锁。

自旋锁的不足之处:

自旋锁一直占用着CPU,他在未得到锁的状况下,一直运行(自旋),因此占用着CPU,若是不能在很短的时间内得到锁,这无疑会使CPU效率下降。

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

所以咱们要慎重使用自旋锁,自旋锁只有在内核可抢占式或SMP的状况下才真正须要,在单CPU且不可抢占式的内核下,自旋锁的操做为空操做。自旋锁适用于锁使用者保持锁时间比较短的状况下。

相关文章
相关标签/搜索