Chinaunix首页 | 论坛 | 博客
  • 博客访问: 264587
  • 博文数量: 52
  • 博客积分: 1379
  • 博客等级: 大尉
  • 技术积分: 525
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-18 17:34
文章分类

全部博文(52)

文章存档

2011年(48)

2010年(4)

分类: LINUX

2011-03-12 12:23:37

pthread_mutex_t 有3种类型, fast, recursive, error checking
recursive运行递归调用lock, error checking立即返回死锁错误
fast比较常见,默认的锁是fast的,其它两种其实可以不需要,自己可以知道自己是否持有锁
锁可以是多线程之间共享(private),或者进程间,默认是private,这影响futex的处理方式

mutex的核心是个lock字段,该值为0代表锁是解开的,1标示被人占用,2表示被人占用的同时又有
线程试图加锁而去睡眠

如果锁竞争不激烈, 即较少碰到锁被占用
那么pthread_mutex_lock,只需要原子的执行一条cmpxchg类似的指令,把lock设置为1并且发现其原来
的值是0, 就成功了
这种情况下不需要睡眠,不需要进行futex系统调用

只有需要睡眠(锁竞争),才用futex通知内核



通过lock; cmpxchg这样的指令原子的检查lock 字段的值, 如果


Compare EAX with r/m32. If
equal, ZF is set and r32 is
loaded into r/m32. Else,
clear ZF and load r/m32 into
EAX.


  1. #define lll_lock(futex) \
  2. (void) \
  3. ({ int ignore1, ignore2;  \
  4. __asm __volatile (
  5. "cmpl $0, %%gs:%P6\n\t" \
  6. "je 0f\n\t" \
  7. "lock\n" \
  8. "0:\tcmpxchgl %1, %2\n\t"
  9. "jnz _L_lock_%=\n\t" \
  10. ".subsection 1\n\t" \
  11. ".type _L_lock_%=,@function\n" \
  12. "_L_lock_%=:\n" \
  13. "1:\tleal %2, %%ecx\n" \
  14. "2:\tcall __lll_lock_wait_private\n" \
  15. "3:\tjmp 18f\n" \
  16. "4:\t.size _L_lock_%=, 4b-1b\n\t" \
  17. ".previous\n" \
  18. LLL_STUB_UNWIND_INFO_3 \
  19. "18:" \
  20. : "=a" (ignore1), "=c" (ignore2), "=m" (futex) \
  21. : "0" (0), "1" (1), "m" (futex), \
  22. "i" (MULTIPLE_THREADS_OFFSET) \
  23. : "memory"); \
pthread_mutex_lock 简化之后的就是这样
如果没有竞争
  1. "jnz _L_lock_%=\n\t"
这条指令就不会执行,这段代码就结束了
否则调用 __lll_lock_wait_private , 该函数把lock设置为2,调用futex睡眠
该函数在调用futex睡眠之前锁有可能被释放了,所以futex的val参数为2,保证如果不是2就不会真正睡眠
否则永远将不会被唤醒了

futex的实现检查的lock是否等于2和被唤醒的动作是互斥的
kernel/futex.c
    ret = get_futex_value_locked(&uval, uaddr);
   

    if (uval != val) {
        表明正想睡眠的时候锁却被解开了
        queue_unlock(q, *hb);
        ret = -EWOULDBLOCK;
    }


pthread_mutex_unlock类似,如果发现原来的值是1,就不需要唤醒了,否则执行唤醒一个线程

如果被锁保护的代码不会阻塞,比较快能执行完,pthread_spin_lock 或许是一个不错的选择


阅读(5315) | 评论(0) | 转发(0) |
0

上一篇:pthread_exit

下一篇:errno

给主人留下些什么吧!~~