简介
自旋锁与互斥锁类似,但是自旋锁不会引起调用者睡眠。如果自旋锁被其他执行单元保持,则调用者会一直循环等待保持者释放锁。
想像这么一个场景,早上醒来你要上厕所(临界区),进入该厕所需要一把钥匙(自旋锁),你发现厕所关着,里面有人了(锁被保持了),你敲门申请,在门外一直等待(循环等待,不会挂起睡眠,而互斥锁会),直到里面的人出来,把钥匙给你(保持着释放锁,你获得锁),进入厕所。
自旋锁的效率远高于互斥锁。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。
自旋锁相关API
关于自旋锁的API,在内核include/linux/spinlock.h里面有,具体要用到自旋锁保护临界区时,可以再去查询各个函数的作用。
static inline void spin_lock(spinlock_t *lock) { raw_spin_lock(&lock->rlock); } static inline void spin_lock_bh(spinlock_t *lock) { raw_spin_lock_bh(&lock->rlock); } static inline int spin_trylock(spinlock_t *lock) { return raw_spin_trylock(&lock->rlock); } #define spin_lock_nested(lock, subclass) \ do { \ raw_spin_lock_nested(spinlock_check(lock), subclass); \ } while (0) #define spin_lock_bh_nested(lock, subclass) \ do { \ raw_spin_lock_bh_nested(spinlock_check(lock), subclass);\ } while (0) #define spin_lock_nest_lock(lock, nest_lock) \ do { \ raw_spin_lock_nest_lock(spinlock_check(lock), nest_lock); \ } while (0) static inline void spin_lock_irq(spinlock_t *lock) { raw_spin_lock_irq(&lock->rlock); } #define spin_lock_irqsave(lock, flags) \ do { \ raw_spin_lock_irqsave(spinlock_check(lock), flags); \ } while (0) #define spin_lock_irqsave_nested(lock, flags, subclass) \ do { \ raw_spin_lock_irqsave_nested(spinlock_check(lock), flags, subclass); \ } while (0) static inline void spin_unlock(spinlock_t *lock) { raw_spin_unlock(&lock->rlock); } static inline void spin_unlock_bh(spinlock_t *lock) { raw_spin_unlock_bh(&lock->rlock); } static inline void spin_unlock_irq(spinlock_t *lock) { raw_spin_unlock_irq(&lock->rlock); } static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) { raw_spin_unlock_irqrestore(&lock->rlock, flags); } static inline int spin_trylock_bh(spinlock_t *lock) { return raw_spin_trylock_bh(&lock->rlock); } static inline int spin_trylock_irq(spinlock_t *lock) { return raw_spin_trylock_irq(&lock->rlock); } #define spin_trylock_irqsave(lock, flags) \ ({ \ raw_spin_trylock_irqsave(spinlock_check(lock), flags); \ }) static inline void spin_unlock_wait(spinlock_t *lock) { raw_spin_unlock_wait(&lock->rlock); } static inline int spin_is_locked(spinlock_t *lock) { return raw_spin_is_locked(&lock->rlock); } static inline int spin_is_contended(spinlock_t *lock) { return raw_spin_is_contended(&lock->rlock); } static inline int spin_can_lock(spinlock_t *lock) { return raw_spin_can_lock(&lock->rlock); }
号主:一枚机械专业本科生,经历了转行,从外包逆袭到芯片原厂的Linux驱动开发工程师,深入操作系统的世界,贯彻终身学习、终身成长的理念。平时喜欢折腾,寒冬之下,抱团取暖,期待你来一起探讨技术、搞自媒体副业,程序员接单和投资理财。【对了,不定期送闲置开发板、书籍、键盘等等】。
如果你想了解我的转行经验,欢迎找我交流~gongzhong号【哆哆jarvis】
一起不断探索自我、走出迷茫、找到热爱,希望和你成为朋友,一起成长~