Java 互斥是如何在内部实现的
我花了一些时间试图理解互斥是如何在几种语言中实现的。有多个链接描述了这个主题(*),但如果我理解正确的话,硬件提供的只是一些原子操作,可能有助于区分现在应该轮到谁 在软件中,这总是用于忙等待(尝试CAS或测试,如果不成功,设置并等待while cycle),但是调度程序如何知道现在我应该从CPU中删除进程/线程,因为它所做的只是等待?在操作系统中是否提供了一些支持,例如Java同步使用这些支持来发出“我被阻止了,请让其他线程运行”的信号?我想是的,因为忙等待是使用lock()的另一种选择;(因此它们不应该是相同的) *资料来源:Java 互斥是如何在内部实现的,java,multithreading,synchronization,mutex,Java,Multithreading,Synchronization,Mutex,我花了一些时间试图理解互斥是如何在几种语言中实现的。有多个链接描述了这个主题(*),但如果我理解正确的话,硬件提供的只是一些原子操作,可能有助于区分现在应该轮到谁 在软件中,这总是用于忙等待(尝试CAS或测试,如果不成功,设置并等待while cycle),但是调度程序如何知道现在我应该从CPU中删除进程/线程,因为它所做的只是等待?在操作系统中是否提供了一些支持,例如Java同步使用这些支持来发出“我被阻止了,请让其他线程运行”的信号?我想是的,因为忙等待是使用lock()的另一种选择;(因此
pthread
库,它是标准C库的一部分。这反过来又使用Linux内核futex
特性(manfutex
)。据我所知,这是使用内核调度器实现的,它将调用线程置于睡眠状态,并在收到信号时将其唤醒
调度器本身依赖于定时器中断(硬件)来工作——本质上,每次定时器中断到来时,调度器都必须检查当前用户空间线程是否需要/必须挂起,如果需要,则必须选择其他线程
这里有几个更清晰、更详细的链接:
这是一个书本级的话题。这本书: 多处理机编程的艺术 莫里斯·赫利希,尼尔·沙维特 ISBN-13:978-0123973375
事实上,还有一个原因是,操作系统提供的用户级互斥量远远不止使用硬件原语。用户级互斥体与操作系统的调度算法密切相关 理解Linux内核 Daniel P.Bovet,Marco Cesati ISBN-13:978-0596005658
在其核心中,互斥体是内核使用的内核对象。它会影响线程的状态(可运行、等待等),而调度程序又会使用这些状态来做出决策。这就是为什么互斥锁并不真正“便宜”,并且经常与优化(如旋转锁)结合使用,旋转锁试图避免内核调用。调度程序不仅由计时器触发。更多(3?!)代码路径触发linux内核中的调度程序。试图获得一个已经被使用的互斥是一个展示。只是一个问题,我想知道我是否理解正确。这意味着,如果我的线程被阻塞,它仍然负责,直到调度程序被唤醒,并看到线程什么也不做?不-在操作系统不可知的术语中-您的应用程序线程使用“takeMutex()”调用内核。在内核空间中的实现中,
takeMutex()
可能会看到已经使用了互斥,并以某种形式调用调度程序。调度程序的计时器触发器主要用于向处于“运行”状态的所有线程授予“公平”时间片。谢谢用户,明白了。我认为还有一些对信号量的支持,与此非常相似。是的,有一整套“内核对象”,互斥就是其中之一。根据操作系统的不同,这还可以包括文件句柄等。