《Pthreads并行编程之spin lock与mutex性能对比分析》有16个想法

  1. 不错 太及时了 最近一门课Distributed Systems的作业就是这个 呵呵

  2. 问一下:
    如果在用户态下使用自旋锁,是否可能被其他线程中断?譬如双核下,有4个线程均需要访问某个资源,该资源使用自旋锁保护(临界区很短,假设10条指令,无阻塞),那么会不会存在某个持有锁的线程被另外一个线程切换导致该核上发生自死锁,导致死循环?例如执行到临界区第3条指令时发生了调度,该核上另外一个等待该自旋锁的线程得到调度。

    1. 就我目前所知,Linux kernel里面实现的spinlock是有防中断的机制的(/kernel/spinlock.c),代码里面有preempt_disable()这样的语句来对当前该核进行防止中断的处理。

      但是你的问题是指用户空间的代码,那么典型的例子就是glic中nptl对pthread_spinlock的实现了,但是我在最新的glibc中没有看到类似kernel中的防中断机制(glibc-2.11/nptl/sysdeps/i386/pthread_spin_lock.c)。所以我只能说我也不确定,保险起见建议你还是用mutex,而且性能也不会差很多。如果你是用Solaris或者FreeBSD的话,它们提供了一种adaptive lock,即先spin一小会儿然后再blocking的锁,又称作spin-then-block lock,你可以参考下。
      不过FreeBSD的内核开发者在2007年对一个类似的问题的回答是pthread spinlock不能防止starvation

    2. 你说的这种情况我觉得不会发生死锁,因为持有锁的线程A被另外一个线程B切换致该核后,线程B会自旋等待锁,当线程B的时间片用完后,线程A会重启调度执行释放锁。

  3. 看来spinlock在用户态的应用场景确实还是比较少的,多谢了。

  4. pthread_spin_lock应该与kernel里面的spin lock一样,锁定的关键区域要比较小才可以。 如果一个线程1获得spin后,另一个线程2在另一个CPU busy-wait该spin lock过程, 如果线程2在跑完此次CPU时间后,仍未获得该spin lock,刚说明,线程1锁的时间太长了。 应该使用mutex,而不应该使用spin lock.

    ——–37 for (j = 0; j < 100000; j++) {

    38 if (g_count++ == 123456789)

    39 printf("Thread %lu wins!n", (unsigned long)gettid());

    40 }
    ————–
    第二个例子中, spin lock的区域是10w次循计和比较操作,并可能带有一个IO操作。 这说明锁的时候太长了。
    这肯定效率低了。

    如果原子操作不能处理,但只保持几行语句的话(不能有sleep的调用),而使用mutex又觉效率不够高的话,可以使用spin lock.

    具体可参考kernel是spin lock锁的范围大小即可。

  5. hi very good blog site and theme. I hope I am not annoying you I simply wanted to inquire just what wordpress plugin you use to show the latest feedback on your blog? I really want to do something along the same lines for my free iphone web page but I cant find the plugin or widget for it. Many thanks for your time 🙂

  6. 你好,想请教一个问题:
    你文中提到:从实现原理上来讲,Mutex属于sleep-waiting类型的锁。例如在一个双核的机器上有两个线程(线程A和线程B),它们分别运行在Core0和Core1上。假设线程A想要通过pthread_mutex_lock操作去得到一个临界区的锁,而此时这个锁正被线程B所持有,那么线程A就会被阻塞(blocking),Core0 会在此时进行上下文切换(Context Switch)将线程A置于等待队列中,此时Core0就可以运行其他的任务(例如另一个线程C)而不必进行忙等待。

    问题1:你提到等待队列,是一个core有一个等待队列呢,还是每个mutex有一个等待队列呢?
    问题2:有这么一个场景:在一个多核机器上,有两个线程要同时写一个公共缓冲区,因此给他们加上pthread_mutex_lock互斥锁,一个线程写的很频繁,另一个线程写的没那么频繁,那么他们竞争互斥锁的情况是怎样的呢?会不会写的没那么频繁的那个线程竞争互斥锁占劣势,或者被调度不到?
    谢谢!

    1. 问题1:文中指的是Core上的等待队列(其实是操作系统的等待队列,因为调度是由OS决定的)。当然,mutex本身也有等待队列,所以线程A肯定也会被添加到mutex的等待队列中去。
      问题2:pthread库的mutex实现应该已经把调度的公平性考虑在内了,所以写操作不太频繁的线程应该也能获得这个锁,不会出现调度不到的情况。具体的可能跟你使用的pthread库的版本有关,越新的越好。你可以实际测试下看看。

  7. hi,guancheng.我看了一下sanos中的mutex.h,mutex.c的实现。
    我有一些疑惑,我不太清楚mutex的lock的3种值的意义,lock=0是很清晰的。但是1和-1的区别就不太清晰了。

  8. 我想问下mutex的实现机制是什么呢?有木有专门介绍呢,谢啦

电子邮件地址不会被公开。 必填项已用*标注