Spin_lock和互斥锁定顺序

时间:2015-03-26 09:14:26

标签: linux-kernel locking

我得到了测试问题(面试)。

  

你需要抓住spin_lock和互斥锁才能做某事。    获得的正确顺序是什么?为什么呢?

我对此有一些想法,但对答案没有强烈的意见。

2 个答案:

答案 0 :(得分:2)

为什么你应该锁定gros是保护"关键区域"在SMP或"关键区域"在单CPU上从抢占相对腐败(种族)。机器类型SMP或单CPU非常重要。 spin和mutex中的代码也很重要。是否有kmalloc,vmalloc,mem_cache_alloc,alloc_bootmem或具有__user内存访问权限的功能甚至是usleep。

spin_lock - 它是/include/asm/spinlock.h中最简单的锁。在同一时间内只能在spin_lock内锁定一个线程。将尝试获取spin_lock的任何其他线程将在同一位置(指令)旋转,直到前一个线程将释放spin_lock。 Spined线程不会进入睡眠状态。因此,与spin_lock同时,您可以拥有两个或更多线程来执行某些操作(一个工作和一个旋转)。在单CPU机器上是不可能的。但对SMP的工作非常好。 spin_lock中的代码部分应该小而快。如果您的代码应该在不同的机器上工作,请尝试检查CONFIG_SMP和CONFIG_PREEMPT。

互斥 - 另一方面工作舔信号量/inside/asm/semaphore.h但是反击是一个。如果counter是1,那么只有一个线程可以进入互斥锁区域。任何其他尝试获取锁定的线程都会看到计数器为零,因为内部有一个thrad。并且线程将进入等待队列。当释放互斥锁并且计数器等于1时,它将被唤醒。互斥锁内的线程可以睡眠。它可以调用内存分配函数并获取用户空间内存。

(SMP)所以想象你有自旋锁和下一个互斥锁。因此,只有一个线程可以获得第一个旋转和下一个互斥。但是潜在的互斥锁代码可能无法入睡,这很糟糕。因为互斥内旋。

(SMP)如果您将获得互斥锁和下一次旋转锁定。同样的情况只有一个线程可以进入锁定区域。但是在互斥锁获取锁定和自旋锁定代码之间可以睡眠,并且在spin_unlock和互斥锁之间也可以睡眠。旋转锁定将会减少非睡眠区域,并且很好。

答案 1 :(得分:1)

TL; DR:首先锁定互斥锁然后旋转锁定。


首先,你需要避免这种情况,并且要小心避免死锁

然后,你应该考虑锁定的影响。 Mutex 可能导致线程阻塞和休眠,而自旋锁可能导致线程在忙等待循环中占用处理器。因此,一般建议保留拥有自旋锁的关键部分,这会导致遵循以下经验法则:在拥有自旋锁时不要睡眠(即通过锁定互斥锁)< / strong>或者你会浪费CPU时间。