Linux机制-锁-自旋锁

  自旋锁和互斥锁有点类似,但是想象一种情况:线程要获取互斥锁,没有得到此锁,就进入睡眠状态,但是此锁的保持时间一般都非常的短,进入睡眠的线程立刻被唤醒。那么进入睡眠,再到被唤醒这个过程的代价就有点大了,此时最好的方法是不要让线程进入睡眠,而是不停的去查看锁是否释放,那么这种情况下就需要使用自旋锁,而不是互斥锁。
   当情况不同,我们选择不同的锁。如果锁的保持时间一般很短,最好是使用自旋锁,这样就有很高的效率,因为省去了睡眠和唤醒的代价。如果锁的保持时间长,最好使用互斥锁,因为如果线程不停的去“自旋”查看锁是否释放,那CPU就白白浪费了。
   【include/linux/spinlock_types.h】
    自旋锁的普遍的定义和初始化函数。
typedef struct {
 raw_spinlock_t raw_lock;
#ifdef CONFIG_GENERIC_LOCKBREAK
 unsigned int break_lock;
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
 unsigned int magic, owner_cpu;
 void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
 struct lockdep_map dep_map;
#endif
} spinlock_t;
                   spinlock_t的结构体定义

    如何初始化一个自旋锁?
    Linux定义了一个宏,用于初始化一个自旋锁。代码如下:
----------------------------------------------------------------------------------------------------------------
# define __SPIN_LOCK_UNLOCKED(lockname)     \
 (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \
    .magic = SPINLOCK_MAGIC,  \
    .owner = SPINLOCK_OWNER_INIT,  \
    .owner_cpu = -1,   \
    SPIN_DEP_MAP_INIT(lockname) }
--------------------------------------------------------------------------------------------------------------------

    并且又定义了一个宏,DEFINE_SPINLOCK()其中的区别请参照源代码中的一段注释:
----------------------------------------------------------------------------------------------------------------------------
/*
 * SPIN_LOCK_UNLOCKED and RW_LOCK_UNLOCKED defeat lockdep state tracking and
 * are hence deprecated.
 * Please use DEFINE_SPINLOCK()/DEFINE_RWLOCK() or
 * __SPIN_LOCK_UNLOCKED()/__RW_LOCK_UNLOCKED() as appropriate.
 */
----------------------------------------------------------------------------------------------------------------------------
#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x)
 
    自旋锁是内核中常用的锁。
    加锁是对数据而不是代码,所有的自旋锁在本质上是不可中断的。
    自旋锁可以使用在中断处理程序中,而信号量则不能,因为信号量可能导致睡眠。在中断处理程序中使用自旋锁时,一定要在获取锁之前,首先禁止本地中断(在当前处理器上的中断请求),否则中断处理程序就会打断正持有锁的内核代码,有可能试图去争用这个已经被持有的自旋锁。
    适用于自旋锁的核心规则是:任何拥有自旋锁的代码都必须是原子的。它不能被休眠,事实上,它不能因为任何原因放弃处理器,除了服务中断以外。内核抢占的情况由自旋锁代码本身处理,任何时候,只要内核代码拥有自旋锁,在相关处理器上的抢占就会被禁止。
    函数spin_lock_bh用于获取指定锁,同时它会禁止所有下半部的执行。由于下半部会抢占进程上下文中的代码,所以当下半部与进程上下文共享数据时,必须对进程上下文中的共享数据进行保护。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值