Linux中的并发与竞争(2)最简单的自旋锁概念及范例

前情提要:
Linux中的并发与竞争(1)并发是如何发生的以及原子操作介绍

1.自旋锁概念及优缺点

自旋锁(spin lock):对共享资源进行互斥访问,采用循环加锁 -> 等待的机制。当一个线程尝试去获取某一把锁的时候,如果这个锁此时已经被别人获取(占用),那么此线程就无法获取到这把锁,该线程将会等待,间隔一段时间后会再次尝试获取。自旋锁只使用短时间的轻量级加锁。
image.png

自旋锁的优点:如果持有锁的线程能在短时间内释放锁资源,那么竞争锁就不需要做内核态和用户态之间的切换,只需要等到持有锁的线程释放锁,避免了用户进程和内核切换的消耗。
自旋锁的缺点:长时间上锁的话,自旋锁会非常耗费性能,它阻止了那些等待锁的线程运行和调度。

2.自旋锁API

2.1普通自旋锁

Linux内核使用 spinlock_t表示自旋锁 ,在include/linux/spinlock_types.h文件中定义

typedef struct spinlock {
	union {
		struct raw_spinlock rlock;

#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))
		struct {
			u8 __padding[LOCK_PADSIZE];
			struct lockdep_map dep_map;
		};
#endif
	};
} spinlock_t;

API如下:

DEFINE_SPINLOCK(spinlock_t lock) 				//定义并初始化一个自选变量。
int spin_lock_init(spinlock_t *lock) 			//初始化自旋锁。
void spin_lock(spinlock_t *lock) 				//获取指定的自旋锁,也叫做加锁。
void spin_unlock(spinlock_t *lock) 				//释放指定的自旋锁。
int spin_trylock(spinlock_t *lock) 		//尝试获取指定的自旋锁,如果没有获取到就返回 0
int spin_is_locked(spinlock_t *lock)	//检查指定的自旋锁是否被获取,如果没有被获取就返回非 0,否则返回 0。
void spin_lock_irq(spinlock_t *lock) 	//禁止本地中断,并获取自旋锁。
void spin_unlock_irq(spinlock_t *lock)	 //激活本地中断,并释放自旋锁。
void spin_lock_irqsave(spinlock_t *lock, unsigned long flags)	//保存中断状态,禁止本地中断,并获取自旋锁。
void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) //将中断状态恢复到以前的状态,并且激活本地中断,释放自旋锁。

2.2读写自旋锁

读写自旋锁:为读和写提供了不同的锁,当没有写操作时,允许多个线程使用读锁,进行并发的读取操作。更适用于读取场合更多的情况

Linux内核中使用 rwlock_t 结构体表示读写锁
image.png

3.自旋锁配合中断使用

DEFINE_SPINLOCK(lock) /* 定义并初始化一个锁 */
 
/* 线程 A */
void functionA (){
    unsigned long flags; /* 中断状态 */
    spin_lock_irqsave(&lock, flags) /* 获取锁 */
    /* 临界区 */
    spin_unlock_irqrestore(&lock, flags) /* 释放锁 */
}

/* 中断服务函数 */
void irq() {
    spin_lock(&lock) /* 获取锁 */
    /* 临界区 */
    spin_unlock(&lock) /* 释放锁 */
}

在进入临界区时,线程A获取到锁,并且保存中断状态,禁止了中断,防止被中断服务打断而造成死锁现象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值