免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6515 | 回复: 11
打印 上一主题 下一主题

不同的自旋锁之间会有冲突吗? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-29 07:37 |只看该作者 |倒序浏览
举个简单的例子:
------------------
      (1) module_A 中使用自旋锁 a
      (2) module_B 中使用自选所 b

      会不会出现由于自旋锁 a 一直在占用 CPU 资源,而使得自旋锁 b 的操作受到影响?

论坛徽章:
1
天蝎座
日期:2013-10-23 21:11:03
2 [报告]
发表于 2010-06-29 09:06 |只看该作者
自选锁不就是一直占用CPU吗
另外,如果单纯使用A,持有自选锁,除非A使用了B的功能,要不怎么切换呢

论坛徽章:
0
3 [报告]
发表于 2010-06-29 10:13 |只看该作者
回复 1# shi_wen_qiang


    你的问题是什么意思啊?一个cpu不可能去同时要求两把锁吧,如果有两把锁配合使用也是串行获得的。

论坛徽章:
0
4 [报告]
发表于 2010-06-29 10:20 |只看该作者
单核CPU,在等待自旋锁a的时候,肯定不会去等待b.
多CPU,如果2个module在不同CPU上,那就2个CPU都忙等。否则和单CPU没区别。

正常的房屋结构的话,厕所门的锁和厨房门的锁是不会有冲突的吧。

论坛徽章:
0
5 [报告]
发表于 2010-06-29 16:15 |只看该作者
回复 4# star1983653


    单cpu不需要自旋锁吧(超线程不知道),自旋锁就是为SMP设计的吧。

论坛徽章:
0
6 [报告]
发表于 2010-06-29 23:35 |只看该作者
ls is correct.

论坛徽章:
0
7 [报告]
发表于 2010-06-30 08:07 |只看该作者
回复  star1983653


    单cpu不需要自旋锁吧(超线程不知道),自旋锁就是为SMP设计的吧。
kgn28 发表于 2010-06-29 16:15



   
不明白其中的含义,可以解释吗?

我不觉得单 CPU 就不能使用自旋锁啊。
例如:
       d 是一个硬件资源,里面有很多的寄存器,可以控制设置 d.
       假设 d 有很多 API
       api_1, api_2, api_3, api_4
       这些 api 的作用就是写寄存器来控制 d.

       那么这些 api 在访问 d 的时候应该用“自旋锁”,使得依次访问硬件资源,不能同时访问硬件资源。

论坛徽章:
0
8 [报告]
发表于 2010-06-30 10:08 |只看该作者
本帖最后由 kgn28 于 2010-06-30 10:12 编辑

回复 7# shi_wen_qiang


    不明白你说的是什么意思。你的意思是这段代码是内核态执行的吧(可能是驱动?)。

    你自己先要知道那些是临界区,然后在临界区的概念上面考察互斥保护。

    如果是在内核态执行,首先程序调用要保证正确的顺序,其次,如果是单CPU,只需要禁止内核抢占就可以保证临界区的安全了。或者禁止中断也可以,当然这些开销可能有些大,可以通过信号量来保护临界区。

    如果是多CPU,需要考虑的问题更多,所以才需要自旋锁,意思就是仅仅在单cpu上保护临界区的手段(禁用抢占【只是在那个cpu上执行的进程禁止抢占】和禁用本地中断)都无法保证临界区的安全,所以才需要自旋锁,保证一个cpu上的内核控制路径(cpu control path)想要访问另外一个cpu上面内核控制路径正在使用的变量(临界区)时让这个cpu一直处于忙等待的状态,仅次而已,而且这个cpu的当前内核控制路径所处的进程态进程如果可以抢占的话,还可以被交换出去!
   简而言之就是:
      cpu a 上的A进程访问 reg1
      cpu b 上的B进程访问 reg1的时候发现自旋锁忙,就执行for语句(假设),直到cpu a的A进程放弃reg1的控制权。

   如果是在单cpu上,cpu a 的A进程和B进程都需要访问reg1,这只需要禁止内核抢占(因为这样A运行的时候【内核态】永远(除非退出内核态)不会schedule到B)或者关闭中断(也不会被schedule到B)就可以使得B没有机会运行,因为只有一个cpu!

论坛徽章:
0
9 [报告]
发表于 2010-07-06 06:02 |只看该作者
回复  shi_wen_qiang


    不明白你说的是什么意思。你的意思是这段代码是内核态执行的吧(可能是驱动 ...
kgn28 发表于 2010-06-30 10:08


谢谢楼上的回答,你说的真详细 ^_^

论坛徽章:
0
10 [报告]
发表于 2010-07-06 07:02 |只看该作者
本帖最后由 shi_wen_qiang 于 2010-07-06 07:41 编辑

关于 spin_lock_irqsave 我想再确认几个事情:
(1) 对于单CPU来说,这句话等价于 “关闭中断” 是吧?(编译时自动去除了和自旋锁相关的东西)
     如果是这样的话,我可不可以这样理解:
     既然在编译时,编译器能自动根据实际使用中CPU的个数来对这个函数(或宏定义)调节,那么我们写代码的时候,加上它肯定是不会有问题的?

(2) 在使用 spin_lock_irqsave 关闭中断后,如果在这么一点时间内,恰好来了一个中断被屏蔽了,等到 spin_unlock_irqrestore 的时候,这个中断应该不会丢失吧?

(3) 下面的自旋锁流程合法吗?

      spin_lock_irqsave( A ) ;
      .....
              spin_lock_irqsave( B ) ;
              ...
              spin_unlock_irqrestore( B ) ;
      ....
      spin_unlock_irqrestore( A ) ;

      ================
      我自己的理解:
            如果在多 CPU 的环境中,这样写法是没有问题的,因为A,B代表两个不同的资源。
            如果在单 CPU 的环境中,这样写可能到导致中断的多次禁用与开启,这样的代码有问题么?

(4) 如果按照上面大家讨论的结论:自旋锁只对多CPU时才是有用的,那么对于单 CPU 时,有没有那种普通的锁?大家也知道,在中断处理程序中,是不能使用信号量来对资源进行控制的,应该使用锁,那对于单CPU,在中断处理程序中,应该使用什么样的锁?

(5) 关于如何禁止内核抢占的问题
     下面这句段是我搜索关键字“禁止内核抢占”得到的:
    -------------------------------------------------------
     为了支持内核抢占,内核引入了preempt_count字段,该计数初始值为0,每当使用锁时加1,释放锁时减1。当preempt_count为0时,表示内核可以被安全的抢占,大于0时,则禁止内核抢占。该字段对应三个不同的计数器(见软中断一节),也就是说在以下三种任何一种情况,该字段的值都会大于0。
     (1)    内核执行中断处理程序时,通过irq_enter增加中断计数器的值;
              #define irq_enter()        (preempt_count() += HARDIRQ_OFFSET)
     问题:通过上面粉色的字,可以看出,只要使用“锁”和“中断”,那么就会自动禁止内核抢占,这里的锁指的也是“自旋锁”吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP