如果两个theads同时锁定一个互斥锁会怎么样?

时间:2011-09-10 17:01:28

标签: multithreading concurrency thread-safety theory mutex

我对互斥体如何工作感兴趣。我了解他们的目的,因为我找到的每个网站都解释了他们的所作所为,但我无法理解在这种情况下会发生什么:

  

有两个线程同时运行,它们试图同时锁定互斥锁。

这在单核上不会出现问题,因为这种情况永远不会发生,但在多核系统中,我认为这是一个问题。我看不出有任何方法可以防止这样的并发问题,但它们显然存在。

感谢您的帮助

2 个答案:

答案 0 :(得分:8)

2个线程无法锁定系统范围的Mutex,一个将锁定,另一个将被阻止。

  

互斥锁/锁的语义!确保只能执行一个线程   在任何时候超越锁定电话。到达的第一个线程   该调用获取互斥锁上的锁定。任何以后的线程都会阻塞   在拨打互斥锁/锁!直到拥有锁的线程   使用互斥锁/解锁释放锁定。

就如何实现这一点而言,请查看test-and-set

  

在计算机科学中,测试和设置指令是一条指令   用于写入内存位置并将其旧值作为a返回   单原子(即不可中断)操作。如果多个   进程可以访问相同的内存,如果进程当前   执行测试和设置,没有其他过程可以开始另一个   测试并设置直到第一个过程完成。 CPU可能会使用   其他电子元件提供的测试和设置指令   作为双端口RAM; CPU还可以提供测试和设置指令   自己。

     

如果旧值为0,则调用进程获取锁定。它旋转   将1写入变量,直到发生这种情况。

答案 1 :(得分:6)

正确实现互斥锁时,永远不能同时锁定互斥锁。为此,您需要一些具有有用属性的原子操作(保证在某一时刻发生在对象上的唯一操作)。

x86架构中的一个此类操作是xchg(交换)。例如,xchg eax, [ebp]将读取地址ebp的值,将eax中的值写入地址ebp,然后将eax设置为读取值,同时保证这些操作不会与对该地址的并发读写交错。

现在您可以实现互斥锁。要锁定,请将1加载到eax,使用互斥锁的值交换eax,然后查看eax。如果它是1,它已被锁定,因此您可能想睡觉并稍后再试。如果是0,则只需锁定互斥锁即可。要解锁,只需将0的值写入互斥锁。

请注意,我在这里重点介绍了重要细节。例如,x86的xchg足够原子,可以在单个处理器上进行先发制人的多任务处理。当您在多个处理器之间共享内存时(例如在多核系统中),除非您使用lock前缀(例如lock xchg eax, [ebp],而不是xchg eax, [ebp],否则它是不够的。 ),ensures that only one processor can access that memory while the instruction is executed