内核自旋锁

概念

锁一般都是用来保护一个临界资源(大抵是全局静态变量这种)的,防止一个在访问时,另外一个程序也来访问
一般使用于运行和等待时间较短的

内核当发生访问资源冲突的时候,可以有两种锁的解决方案选择:一个是原地等待 一个是挂起当前进程,调度
其他进程执行(睡眠)。

Spinlock 是内核中提供的一种比较常见的锁机制,自旋锁是“原地等待”的方式解决资源冲突的,即:
一个线程获取了一个自旋锁后,另外一个线程期望获取该自旋锁,获取不到,只能够原地“打转”(仍然占用CPU,并不是休眠:忙等待)。
所以自旋锁不会导致线程状态的切换,一直处于用户态 即线程一直都是 active 的。不会使线程进入阻塞状态,减少了不必要的上下文切换,执行速度快。
(上下文切换:当程序休眠时,CPU会切换到其他程序处,然后再切换回来)

注意事项

进程拥有自旋锁的时候,该 cpu 上是禁止抢占的;只要进入自旋,就一直占据CPU;

一般用于多 cpu 之间的资源竞争;

由于自旋锁的这个忙等待的特性,注定了它使用场景上的限制,自旋锁不应该被长时间的持有(消耗 CPU资源),一般应用在中断上下文

定义和使用

动态的:
spinlock_t lock;
spin_lock_init (&lock);
静态的:
DEFINE_SPINLOCK(lock);

加锁
spin_lock(&lock);
解锁
spin_unlock(&lock);

1、我们要访问临界资源需要首先申请自旋锁;
2、获取不到锁就自旋,如果能获得锁就进入临界区;
3、当自旋锁释放后,自旋在这个锁的任务即可获得锁并进入临界区,退出临界区的任务必须释放自旋锁。

static spinlock_t lock;
static int flag = 1;


static int hello_open (struct inode *inode, struct file *filep)
{
	printk("hello_open()\n");
	spin_lock(&lock);
	if(flage != 1)
	{
		spin_unlock(&lock);
		return -EBUSY;
	}
	flag = 0;
	spin_unlock(&lock);	
	return 0;
}

static int hello_release (struct inode *inode, struct file *filep)
{
	printk("hello_release()\n");
	flage = 1;
	return 0;.
}

自旋锁保护的是flag,当flag为1的时候可以继续进行;
注意:当上锁之后因为任何情况而退出时,都要释放锁

死锁

1、拥有自旋锁的进程 A 在内核态阻塞了,内核调度 B 进程,碰巧 B 进程也要获得自旋锁,此时 B 只能自旋转 。 而此时抢占已经关闭(单核)不会 调度 A 进程了 B 永远自旋,产生死锁 。

2、进程 A 拥有自旋锁,中断到来,CPU 执行中断函数中断处理函数 中断处理函数需要获得自旋锁 访问共享资源,此时无法获得锁 只能自旋 产生死锁 。
在这里插入图片描述
主要原因:进入sleep暂时不会占用CPU,结果CPU被趁虚而入,被自旋锁占用;无法再运行别的命令。
在这里插入图片描述
自旋锁最核心的问题就是申请不到锁,就会一直占据一个CPU;如果这个锁一直不被释放那么就会导致死锁;不被释放可能是由于带锁的程序被自旋锁抢占了CPU,或者自己出不来了等等。

如何选择锁

在这里插入图片描述
1、在中断中只能使用自旋锁是为了快,尽可能少的占用CPU时间;
2、任务睡眠使用互斥体;

互斥体和信号量

互斥体和信号量很相似,内核中两者共存会令人混淆。所幸,它们的标准使用方式都有简单规范:除非 mutex 的某个约束妨碍你使用,否则相比信号量要优先使用 mutex 。

当你写新代码时,只有碰到特殊场合(一般是很底层代码)才会需要使用信号量。因此建议选 mutex 。如果发现不能满足其约束条件,且没有其他别的选择时,再考虑选择信号量。

问题是互斥体只限于一个访问,信号量可以多个坑位。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值