【问题标题】:What happens when two threads ATTEMPT to lock the same resource at the exact same time?当两个线程试图同时锁定同一个资源时会发生什么?
【发布时间】:2012-07-28 16:38:01
【问题描述】:

当两个线程尝试在完全相同的微秒内(或任何可以测量 CPU 片或指令的最短时间长度)锁定同一个对象时会发生什么?

两个线程是否有可能在完全相同的并发时间执行指令,或者这对于当今的硬件来说是不可能的?

我正在从事一个处理多线程的项目,可以这么说,任何线程都可能击败另一个线程到达终点线。所以很自然地,“当它们都同时锁定时会发生什么?”的问题。必须解决 IMO。

【问题讨论】:

  • '当它们同时锁定时会发生什么?'根据定义,这是不可能的。如果这样的事情可能发生,那不是锁。
  • 也许可以用另一种方式来提出这个问题:当多个线程达到该点时,锁的行为如何?好吧,我猜内部工作将对对该资源的访问进行排队,唯一的失败情况是当您涉及对不同资源的多个顺序访问并且您遇到所谓的死锁时。无论如何,锁定点是在资源被释放给其他人之前让完整的代码块完成。否则你不会被授予,你的逻辑可能会失败
  • Diego De Vita 正确解释了我的问题。应该重申“当两个线程试图锁定同一个资源时会发生什么?”
  • @MartinBliss - 只有一个会成功。另一个要么立即收到失败返回,要么被拒绝执行,直到成功获得锁的线程释放锁,(或者,有时,直到超时间隔过去而没有获得锁,导致“超时” -失败'返回)。

标签: .net multithreading locking


【解决方案1】:

这是不可能的,锁无法做到它们所承诺的。这需要处理器支持,因为它是唯一可以确保多个内核不会尝试同时访问同一内存位置的处理器。一个例子是这段汇编代码,由 x86 版本的 CLR 在其 Monitor.TryEnter() 方法中使用:

FASTCALL_FUNC CompareExchangeUP,12
        _ASSERT_ALIGNED_4_X86 ecx
        mov     eax, [esp+4]    ; Comparand
        cmpxchg [ecx], edx
        retn    4               ; result in EAX
FASTCALL_ENDFUNC CompareExchangeUP

cmpxchg 处理器指令提供原子性保证。这是任何现代内核都具有的指令,它的通用名称是“比较和交换”。您可以在 Wikipedia article 中找到有关此说明的更多信息。

【讨论】:

    【解决方案2】:

    在几乎所有环境中,现代锁的设计都使得两个线程不可能同时锁定一个对象。 现代处理器有可能在两个不同的内核上运行两个线程几乎同时尝试获取锁,但它们都实现了允许软件告诉它们不允许的同步机制.

    例如,x86-64 有 MONITORMWAIT 指令。它们基本上在微处理器级别实现了 .NET 的 lock(){}System.Threading.Monitor.Wait()System.Threading.Monitor.Enter()/.Exit() 的语义。

    【讨论】:

    • 是的,但是在 .net 环境中,我们讨论的是语言域以及运行时在这种情况下的行为方式。我的回答是:如果你不锁定共享资源,他们的访问将不是线程安全的,你的逻辑可能会被完全搞砸
    • 我喜欢 sblom 的回答。我认为计算机硬件会有某种指令同步机制,但我想在做出这个假设之前确定...谢谢 sblom!
    猜你喜欢
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多