免费注册 查看新帖 |

Chinaunix

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

问一个自旋锁的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-29 22:40 |只看该作者 |倒序浏览
对于自旋锁,一直有些不明白。

   SMP时就不多说了,比较好理解。

   1.UP且内核为抢占式时,以下情况会发生什么?

   A内核线程持有自旋锁时,被B线程抢占,B线程在自旋锁上判断后自旋...

   后来呢? 是不是到了timeslice线程B就让出CPU,让A得到执行的机会?

   还是一直在CPU“疯狂的自旋”?这样的话岂不是要死锁了?

   2.UP且内核为非抢占式的,那么由于持有自旋锁的代码都是原子的,因此不会切换到别的线程执行?

     如果是这样的话,对于UP中的内核为非抢占式的代码来说,自旋锁没有任何意义?是这样吗?

    问题比较弱,还请大家帮忙解答疑惑。谢谢!

------
参考
http://bbs.chinaunix.net/viewthread.php?tid=639557&extra=&highlight=%D7%D4%D0%FD%CB%F8&page=1

论坛徽章:
0
2 [报告]
发表于 2007-10-30 00:02 |只看该作者

回复 #1 grassroot07 的帖子

首先,在原子上下文中(中断上下文、持有自旋锁的上下文)不能睡眠(调用了schedule)。首先因为中断没有进程上下文,spin_lock虽然可能有,但是如果允许,就可能导致死锁。因此:
1.在Linux kernel中,持有自旋锁的上下文时不允许被抢占。参考kernel/sched.c文件schedule函数和kernel/spinlock.c的_spin_lock、_spin_unlock函数。
2.在单CPU的非抢占的内核中,通常spin_lock定义为空!

论坛徽章:
0
3 [报告]
发表于 2007-10-30 14:18 |只看该作者

回复 #2 xhbdahai 的帖子

自旋锁是一个基本的概念:
1.Linux中,没有用户态的自旋锁,spin_lock用在内核中。其作用是为了保护临界资源不会被多个线程同时访问。持有自旋锁的代码区域通常被称作临界区。
2.所谓自旋,就是如果一个内核线程A(B,C或者更多)想要获取这个锁S时,但是这个锁已经被其他内核线程T持有,那么A(B,C和其他)线程将一在一个循环中不停的测试锁S的状态,其中等待线程中(A,B,C或者更多)的某一个线程将在T释放自旋锁S之后获取它而退出测试循环。而其他没有获取到的线程将继续对S的测试。自旋因此而得名!
另外,目前的内核中spin_lock好像没有超时的版本,所以他不会在等待一定时间后停止自旋。除非使用spin_trylock,之测试一次!
3.处于自旋锁保护的临界区对于Kernel来说,属于原子操作区域。Kernel不允许在原子操作区内的进程睡眠(睡眠实质上是由于某种原因而主动让出CPU)。否则,既有可能导致死锁!
4.同样,处于自旋锁保护的临界区内kernel不允许被抢占,抢占会在进入临界区时被禁止。
5.在某些情况下,处于自旋锁的临界区也不能不中断,如果你的中断处理中需要持有同样的自旋锁,那么将会导致死锁。这中情况需要程序员小心处理。对付这种问题,可能会需要在关中断的情况下进入临界区。在处理完临界区之后再使能中断!

论坛徽章:
0
4 [报告]
发表于 2007-10-30 20:24 |只看该作者
“在Linux kernel中,持有自旋锁的上下文时不允许被抢占。”
   
     这样说的话,自旋锁在单CPU的内核中(无论是可抢占还是不可抢占),都没有任何意义了吗?
   
    因为无论怎样也要等到持有自旋锁的线程让出CPU后才可能有其他线程来执行判断啊。

论坛徽章:
0
5 [报告]
发表于 2007-10-30 23:51 |只看该作者
原帖由 grassroot07 于 2007-10-30 20:24 发表
“在Linux kernel中,持有自旋锁的上下文时不允许被抢占。”
   
     这样说的话,自旋锁在单CPU的内核中(无论是可抢占还是不可抢占),都没有任何意义了吗?
   
    因为无论怎样也要等到持有自旋锁的 ...


1. 在非抢占的单CPU系统中,试想,如果自旋锁有效,一个线程在自旋(试图获取这个锁)等待这个锁时会出现什么情况?它将永远自旋下去,因为持有这个锁的线程不会有释放锁的机会!为了避免这种情况,因此这种情况下__raw_spin_lock实现为空,preempt_disable同样也实现为空。

2.在抢占的单CPU系统中 __raw_spin_lock实现为空,但是preempt_disable不为空。意味这spin_lock保护的区域同样是原子的,处于spin_lock保护的临界区不被抢占!

spin_lock在单CPU的内核中,如果在非抢占模式下,spin_lock是没有意义的。但是在抢占模式下却是有意义的,他保证抢占模式下锁临界区操作的原子性!

建议你可以阅读一下schedule()函数,和kernel/spin_lock.c这个文件的源代码。相信你会理解更深!

[ 本帖最后由 xhbdahai 于 2007-10-30 23:57 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2007-11-02 22:12 |只看该作者
多谢你的耐心解释。

  我说一下不知道理解的正确不?,也就是说一段代码

  spin_lock(&lock);
   ...
   原子上下文的临界区
   ...
  spin_unlock(&lock);


  1.在UP非抢占情况下,自旋锁代码实际上什么都没干,直接执行到spin_unlock(原子上下文执行完毕)才有可能让出CPU。
  2.在UP抢占情况下,自旋锁代码只是禁用了抢占,这样也不会发生抢占临界区的情况。

  实际上如果设计正确在单CPU上不会发生判断自旋锁的过程。
  是这样吧?

论坛徽章:
0
7 [报告]
发表于 2007-11-02 23:08 |只看该作者
原帖由 grassroot07 于 2007-11-2 22:12 发表
多谢你的耐心解释。

  我说一下不知道理解的正确不?,也就是说一段代码

  spin_lock(&lock);
   ...
   原子上下文的临界区
   ...
  spin_unlock(&lock);


  1.在UP非抢占情况下,自旋锁代码实际 ...


1.通常在up非抢占模式下,执行在内核代码的进程不能被强占,除非主动让出CPU。
2.yes!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP