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