Linux内核中竞态学习过程的问题

本文详细探讨了中断屏蔽仅在单核CPU上有效的原因、同一进程内多次获取同一把锁时产生的死锁现象、信号量与自旋锁的区别以及互斥体与信号量的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题1: 中断屏蔽为何只对单核有效

在内核中中断屏蔽使用的API为local_irq_disable()和local_irq_enable(),而两者都只能禁止和使能本CPU内的中断,因此并不能解决SMP多CPU引发的静态问题。

其它重要点:

  1. 并且中断屏蔽的临界区要尽量的小,不能有耗时操作,因为在内核中很多操作都依靠中断来出来,长时间的屏蔽中断,可能会导致内核崩溃。
  2. 在开发中很少遇到单核的CPU(老师和网友说的)!!!

问题2:在同一个进程如果多次获取同一把锁此时cpu死锁(执行这个代码的cpu)

进程在第一次获取自旋锁的时候能够成功(没有其他进程获取这个自旋锁的时候),在第二次获取自旋锁的时候就会忙等,一直等待自旋锁被释放,此时这个进程没法继续往下执行,自然也执行不到释放锁的代码,所以会产生死锁。

其它重要点:

  1. 自旋锁是针对多核设计的,对于单核不支持抢占的CPU,自旋锁执行空操作。
  2. 自旋锁在上锁期间会关闭抢占。任何一个核拿到了自旋锁,该核上的抢占调度也暂时禁止了,但是没有禁止另外一个核的抢占调度。
  3. 自旋锁持有的时间必须短,也就是临界区要尽可能的短,只有临界区尽可能的短自旋锁的效率才够高,因为自旋是占用CPU资源的。你持有锁的时间越长,另一个进程可能不得不自旋等你释放锁,长时间的持有锁也阻止了当前处理器调度, 意味着高优先级进程 – 真正应当能获得 CPU 的 – 可能不得不等待。
  4. 自旋锁可以工作在中断上下文,因为中断处理函数中不允许有耗时操作。
  5. 在自旋锁锁定期间不能调用可能引起进程调度的函数。 如果进程获得自旋锁之后再阻塞, 如调用copy_from_user()、copy_to_user()(拷贝时间太长的话,可以让cpu先执行其它的代码,然后再回来执行拷贝)、kmalloc()和msleep()等函数, 则可能导致内核的崩溃。

问题3:信号量和自旋锁的区别

  1. 信号量遵循了让权等待原则,在进程无法获得临界资源的时候进程会进入到休眠态;而自旋锁在获取不到临界资源的时候会一直忙等。
  2. 信号量不会产生死锁,而自旋锁会。
  3. 信号量保护的临界区可以很大,里面可以有延时、耗时、甚至休眠的操作;而自旋锁保护的临界区要尽可能的小
  4. 信号量工作在进程上下文(在进程中使用,不能在中断中使用);自旋锁可以在中断上下中使用。
  5. 信号量上锁的时候是不会关闭抢占的;自旋锁会在上锁后关闭抢占。

问题4:互斥体和信号量的区别

信号量在获取的不到临界资源的时候会直接进入休眠状态,而互斥体会等待一会,再进入休眠。
在进程上下文中,不知道临界区大小的时候,如果需要上锁优先选择互斥体。因为互斥体在获取不到临界资源的时候会稍微等待一会儿,如果要保护的临界区访问时间比较短时,就省去上下文的切换,进程上下文切换的开销也很大,正是因为等待的这个时间,所以临界区比较小的时候互斥体的效率高。
当所要保护的临界区访问时间比较短时, 用自旋锁是非常方便的, 因为它可节省上下文切换的时间。 但是CPU得不到自旋锁会在那里空转直到其他执行单元解锁为止, 所以要求锁不能在临界区里长时间停留, 否则会降低系统的效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值