当对象被锁定在C ++和Java等语言中时,实际上是在低级别上执行了吗?我不认为这与CPU /缓存或RAM有关。我最好的猜测是,这发生在操作系统的某个地方?它是否在执行上下文切换的操作系统的同一部分内?
我指的是锁定对象,同步方法签名(Java)等。
答案可能取决于哪种特定的锁定机制?
答案 0 :(得分:4)
锁定涉及同步原语,通常是互斥锁。虽然天真地说互斥体只是一个布尔标志,表示“锁定”或“未锁定”,但是魔鬼在细节中:必须以原子方式读取,比较和设置互斥量值,以便多个线程尝试使用相同的互斥锁不要破坏它的状态。
但除此之外,必须正确地排序指令,以便读取和写入互斥变量的效果以正确的顺序对程序可见,并且没有线程无意中进入临界区时不应该因为它未能及时看到锁更新。
内存访问排序有两个方面:一个是由编译器完成的,如果认为语句更有效,它可以选择重新排序语句。这是相对微不足道的,因为编译器知道何时必须小心。更困难的现象是内部的CPU本身可能会选择重新排序指令,并且在为了锁定而访问互斥变量时必须阻止这样做。这需要硬件支持(例如,“锁定位”导致管道刷新和总线锁定。)
最后,如果你有多个物理CPU,每个CPU都有自己的缓存,在任何执行指令进一步发展之前,状态更新传播到所有CPU缓存变得很重要。这又需要专用的硬件支持。
正如您所看到的,同步是一种(可能)昂贵的业务,确实妨碍了并发处理。然而,这只是你为一个单独的内存块支付的价格,多个独立的上下文可以在其上运行。
答案 1 :(得分:3)
C ++中没有对象锁定的概念。您通常会在特定于操作系统的功能之上实现自己的功能,或者使用库提供的同步原语(例如boost::scoped_lock
)。如果您有权访问C ++ 11,则可以使用具有类似接口的线程库提供的锁来获取look。
在Java中,JVM也为您完成了同样的工作。
答案 2 :(得分:3)
java.lang.Object
内置了一个监视器。这就是用于锁定synchronized关键字的内容。 JDK 6添加了一个并发包,为您提供更细粒度的选择。
这有一个很好的解释:
http://www.artima.com/insidejvm/ed2/threadsynch.html
我很长时间没有写过C ++,所以我不能说用这种语言怎么做。我上次写这篇文章时,语言不支持它。我相信这都是第三方库或自定义代码。
答案 3 :(得分:0)
它确实依赖于特定的锁定机制,通常是一个信号量,但你不能确定,因为它依赖于实现。
答案 4 :(得分:0)
我所知道的所有体系结构都使用原子Compare And Swap来实现它们的同步原语。例如,参见AbstractQueuedSynchronizer,它在一些JDK版本中用于实现Semiphore和ReentrantLock。