免费注册 查看新帖 |

Chinaunix

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

[内核同步] 用户态自旋锁和内核态自旋锁的区别? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-01-30 16:18 |只看该作者 |倒序浏览
如题,小弟内核菜鸟,最近研究自旋锁,发现用户态也有自旋锁实现(如pthread),不知道用户态下的自旋锁和内核态的区别是什么?
或者说用户态下的自旋锁实现原理是什么?还望大神赐教。

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
2 [报告]
发表于 2015-01-30 17:07 |只看该作者
不负责任的回答,用户的锁最后也用的内核里面的。

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
3 [报告]
发表于 2015-01-31 08:22 |只看该作者
回复 1# DVD0423

我有点不同意amarant的解析,有点以偏概全。

其实这个问题的核心就是什么才叫spinlock?只要符合拿不到锁时自旋等待而是不去睡眠这个条件,就符合自旋锁的定义,它的实现就是一个自旋锁的!不管在那实现,不管最终的实现会有什么其它的效果。
跟拿到锁以后是否还会被调度走没有关系,其实内核的spinlock实现在打开内核抢占时,拿不到锁,也会被调度出去。

http://www.unix.com/man-page/freebsd/3/pthread_spin_lock/
The pthread_spin_lock() function will acquire lock if it is not currently owned by another
     thread.  If the lock cannot be acquired immediately, it will spin attempting to acquire the
     lock (it will not sleep) until it becomes available.



   

论坛徽章:
2
寅虎
日期:2014-11-25 21:47:342015小元宵徽章
日期:2015-03-06 15:58:18
4 [报告]
发表于 2015-01-31 08:37 |只看该作者
回复 3# Tinnal

有个疑问请教下:
内核的spinlock实现在打开内核抢占时,拿不到锁,也会被调度出去。
疑问:内核开抢占时,拿不到锁就被调度,就违背自旋的本意了吧?
   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
5 [报告]
发表于 2015-01-31 08:41 |只看该作者
本帖最后由 Tinnal 于 2015-01-31 08:42 编辑

回复 4# 镇水铁牛


    没有违背呀。1. 从代码来说,它还在自我的循环里;2.它的状态还是running的状态,没有去睡眠等待。

论坛徽章:
0
6 [报告]
发表于 2015-01-31 10:25 |只看该作者
回复 3# Tinnal

下面是linux-2.6.10的代码:
  1. #define spin_lock(lock)                _spin_lock(lock)

  2. void __lockfunc _spin_lock(spinlock_t *lock)
  3. {
  4.         [color=Red]preempt_disable();
  5. [/color]        if (unlikely(!_raw_spin_trylock(lock)))
  6.                 __preempt_spin_lock(lock);
  7. }

  8. static inline void __preempt_spin_lock(spinlock_t *lock)
  9. {
  10.         if (preempt_count() > 1) {
  11.                 _raw_spin_lock(lock);
  12.                 return;
  13.         }

  14.         do {
  15.                 [color=Red]preempt_enable();
  16. [/color]                while (spin_is_locked(lock))
  17.                         cpu_relax();
  18.                 [color=Red]preempt_disable();
  19. [/color]        } while (!_raw_spin_trylock(lock));
  20. }
复制代码
=============================================================
下面是linux-3.10.0的代码:
  1. static inline void spin_lock(spinlock_t *lock)
  2. {
  3.         raw_spin_lock(&lock->rlock);
  4. }

  5. #define raw_spin_lock(lock)        _raw_spin_lock(lock)


  6. void __lockfunc _raw_spin_lock(raw_spinlock_t *lock)
  7. {
  8.         __raw_spin_lock(lock);
  9. }


  10. static inline void __raw_spin_lock(raw_spinlock_t *lock)
  11. {
  12.         [color=Red]preempt_disable();   
  13. [/color]        spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
  14.         LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
  15. }


  16. static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
  17. {
  18.         __acquire(lock);
  19.         arch_spin_lock(&lock->raw_lock);
  20. }

  21. static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
  22. {
  23.         register struct __raw_tickets inc = { .tail = TICKET_LOCK_INC };

  24.         inc = xadd(&lock->tickets, inc);
  25.         if (likely(inc.head == inc.tail))
  26.                 goto out;

  27.         inc.tail &= ~TICKET_SLOWPATH_FLAG;
  28.         for (;;) {
  29.                 unsigned count = SPIN_THRESHOLD;

  30.                 do {
  31.                         if (ACCESS_ONCE(lock->tickets.head) == inc.tail)
  32.                                 goto out;
  33.                         cpu_relax();
  34.                 } while (--count);
  35.                 __ticket_lock_spinning(lock, inc.tail);
  36.         }
  37. out:        barrier();        /* make sure nothing creeps before the lock is taken */
  38. }
复制代码
新版本取消了自旋等待过程中的抢占使能。
   

论坛徽章:
0
7 [报告]
发表于 2015-02-02 09:00 |只看该作者
我知道你的意思,可能我没表述清楚,我想说的是他们的底层是不是一样的,比如X86架构,他们的实现是不是用的相同的指令。因为我最近做的实验是检测自旋锁时间,这样就出现一个问题,到底是只检测内核中的还是也要检测用户层下的?回复 3# Tinnal


   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
8 [报告]
发表于 2015-02-02 13:53 |只看该作者
回复 7# DVD0423


    代码肯定是不一样的呀,而且用户态和内核态没有可比性。

论坛徽章:
0
9 [报告]
发表于 2015-02-02 18:48 |只看该作者
回复 8# Tinnal 我的关键问题就是想知道这两个不一样的地方。比如一个带有自旋锁的程序到底在指令层是不是调用了内核的自旋锁?这涉及到我的自旋锁检测的实验是不是只需要检测内核层,请问您了解吗?求指导。


   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
10 [报告]
发表于 2015-02-03 00:46 |只看该作者
pthread_spin_lock应该是没有调用内核的Spinlock实现的。内核的spinlock不是一个系统调用。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP