linux内核 自旋锁示例,LINUX内核笔记:自旋锁

目录

1、自旋锁作用与基本使用方法?

与其他锁一样,自旋锁也用于保护临界区,但是自旋锁主要是用于在SMP上保护临界区。在SMP上,自旋锁最多只能被一个可执行线程持有,如果一个线程尝试获得一个被争用的自旋锁,该线程将一直旋转(while循环)直到锁可用;如果锁未被争用,请求锁的执行线程将立刻争用它,并继续执行。

LINUX下自旋锁的基本使用方法:

声明锁:

spinlock_t lock;

初始化:

lock = SPIN_LOCK_UNLOCKED;

或者

spin_lock_init(&lock);

加锁有4个接口,3个会阻塞,1个不阻塞

spin_lock(&lock);//获取自旋锁

spin_lock_irq(&lock);//关中断,获取自旋锁,不建议使用

spin_lock_irqsave(&lock, flags);//关中断,保存中断状态,获取自旋锁

spin_trylock(&lock);//与spin_lock一样,但是获取不到的时候不阻塞,返回非0

对应的解锁接口有3个

spin_unlock(&lock);//spin_lock和spin_trylock都用该接口解锁

spin_unlock_irq(&lock);//不建议使用

spin_unlock_irqrestore(&lock, flags);

另外还提供了一个获取锁状态的接口:

spin_is_locked(&lock);//如果指定的锁被获取,返回非0,否则,返回0

2、在SMP和UP上的不同表现?

对于SMP,自旋锁将在禁止抢占后,while循环自旋直到锁可用;

对于UP,自旋锁的行为有点不一样,具体表现为:

内核不支持抢占,则spin_lock是个空函数,spin_unlock也是空函数;

内核支持抢占,则spin_lock关抢占,spin_unlock开抢占。

要分析SMP和UP的区别,还得先理解UP下内核支持抢占与否的区分。

在不支持抢占的时候,内核调度时机为:

内核代码一直要执行到完成(返回用户空间);

阻塞或主动调用schedule();

支持内核抢占的内核,则在以下情况会发生抢占:

从中断处理程序回到内核空间且内核具有抢占性时;

当内核代码再一次具有可抢占性时;(如时钟中断,发现进程时间片已经用完,则发生进程抢占)

内核显式调用schedule();

内核中的任务阻塞(同样导致schedule()); 从以上区别可以看出,若是内核不支持抢占,只要临界区的代码不阻塞,就能保证原子性,所以spin_lock/spin_unlock是空函数。

而对于支持抢占的内核, spin_lock/spin_unlock自然只需要关闭/恢复抢占功能即可。

3、自旋锁与上下文

由于自旋锁不睡眠,既可以用于进程上下文,也可用于非进程上下文,这是它与信号量相比的一个优势。

正常来讲,如果自旋锁都是在进程上下文中使用,则建议使用spin_lock/spin_unlock。

若在中断处理例程中也要使用自旋锁,则所有争用同一个锁的地方应使用spin_lock_irqsave/spin_unlock_irqrestore。

若没有在中断而在下半部使用自旋锁,则所有急用同一个锁的地方可以使用spin_lock_bh/spin_unlock_bh,这对函数平时用得比较少。

注:自旋锁用在中断例程中,若是进程上下文中的内核代码使用spin_lock,则在临界区,可能发生中断 ,要么原子性被破坏(UP),要么造成死锁(SMP).

4、使用spin_lock()后为什么不能睡眠?

在UP下,正如前面所说,原子性得不到保证。

而在SMP下,则可能发生死锁:

假设有3个进程A,B,C,2个CPU称CPU0,CPU1.

CPU0上A进程获取自旋锁进入睡眠,调度了B进程,B进程将自旋;

CPU1上调度了C进程也将自旋。

B等着A释放锁,A等着B释放CPU,自旋后的CPU不能发生调度,CPU0和CPU1将一直自旋下去,形成了死锁。

5、强调:锁什么?

使用锁的时候一定要对症下药,明确保护的是数据而不是代码,这是使用锁的正确思考方式。经常看别人代码的人应该会有所体会,针对代码加锁常常使代码难以理解,特别是复杂的程序,往往加锁没做好,引起竞争条件。

不防在使用锁的时候先思考一下自己要保护什么,然后给对应的锁取跟数据相关的名称。比如"int foo;spinlock_t foo_lock;"表示foo由foo_lock加锁;

6、参考

《Linux内核设计与实现》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值