Linux 同步机制:自旋锁

自旋锁的特点与适用场景

Linux自旋锁spinlock同一时刻只能被一个可执行线程持有。当一个线程试图获取一个已经被持有的spin lock时,就会一直忙循环-选择-等待锁重新可用。忙等待免去了线程挂起再被唤醒的转换,省去了两次上下文切换的时间。因而spinlock适合下面的场景:SMP多核系统中,持有自旋锁的时间小于完成两次上下文切换的时间,这种场景使用spinlock效率会比较高。所以一般在用户态程序中,很少会遇到使用自旋锁的场景,因为用户程序由内核调度,除非绑核一般无法保证两个需要同步的线程恰好分布在两个核上,也很少真正有持有锁时间很短少于两次上下文切换时间的。

Linux spinlock在内核中相对比较常见,因为内核中有很多需要短期加锁的场景,比如在SMP系统的中断上下文中。但是,单核CPU或者禁止内核抢占时,编译的时候自旋锁会被完全剔除出内核。这点也不难理解,单核本质上串行执行任务的,靠时间片分时执行各任务来实现并发,所以单核使用spinlock会忙等待到线程的时间片用完,这是得不偿失的。Linux spinlock不可递归,可用在中断处理程序中,(中断处理程序中不能用信号量,因为会导致睡眠)。一个注意点事:中断处理程序中处理自旋锁时,一定要在获取锁之前,关闭当前核的中断,防止在中断中又去试图获得锁而造成死锁。

spinlock在pthread中的API

/* Initialize the spinlock LOCK.  If PSHARED is nonzero the spinlock can
   be shared between different processes.  */
extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
     __THROW __nonnull ((1));

/* Destroy the spinlock LOCK.  */
extern int pthread_spin_destroy (pthread_spinlock_t *__lock)
     __THROW __nonnull ((1));

/* Wait until spinlock LOCK is retrieved.  */
extern int pthread_spin_lock (pthread_spinlock_t *__lock)
     __THROWNL __nonnull ((1));

/* Try to lock spinlock LOCK.  */
extern int pthread_spin_trylock (pthread_spinlock_t *__lock)
     __THROWNL __nonnull ((1));

/* Release spinlock LOCK.  */
extern int pthread_spin_unlock (pthread_spinlock_t *__lock)
     __THROWNL __nonnull ((1));

用法跟互斥锁(互斥量)类似,这里就不举例了。总之,在用户态程序,极少有场景会适合用自旋锁。目前在实际工程中只见过涉及绑核的高性能转发有使用过,其他业务场景的同步基本靠互斥量和条件变量。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值