互斥体如何实现?
对于特定的应用程序,有些实现比其他实现更好吗 有没有什么可以通过推出自己的?
查看维基百科上testing和设置机器指令的描述,这暗示了在机器级别如何实现primefaces操作。 我可以想象,大多数语言级别的互斥体实现依赖于机器级别的支持,例如testing和设置。
基于Adamski的test-and-set
build议,您还应该考虑“快速用户空间互斥”或futexes的概念 。
互斥锁具有所需的属性,它们在locking或解锁无争用互斥锁的常见情况下不需要内核系统调用。 在这些情况下,用户模式代码成功使用primefaces比较和交换(CAS)操作来locking或解锁互斥锁。
如果CAS失败了,互斥体就会被争用,并且Linux下的内核系统调用sys_futex
必须用来等待互斥量(在locking情况下)或唤醒其他线程(在解锁情况下)。
如果你真的想要自己实现这个,请确保你阅读Ulrich Drepper的论文 。
一个互斥体最好在操作系统的内核中运行,同时保持其周围的代码量尽可能短,这样可以避免在任务切换到另一个进程时被截断。 因此,确切的实施有点秘密。 这并不复杂。 它基本上是一个具有布尔型字段的对象,它可以获取和设置。
- 当使用计数器时,它可以成为一个信号量。
- 互斥体是关键部分的起点,它在内部使用互斥锁来查看是否可以input一段代码。 如果互斥锁是空闲的,它将设置互斥锁并执行代码,只在完成时释放互斥锁。 当关键部分注意到互斥体被locking时,它可以等待互斥体被释放。
在基本的互斥体逻辑周围,有包装器将其包装在一个对象中。然后,使更多的包装器对象在内核之外提供。 然后另一个包装,使其在.NET中可用。 然后,几个程序员将围绕这一切编写自己的包装代码,以满足自己的逻辑需求。 包装纸周围的包装真的使他们一个阴暗的领土。
现在,有了这些有关互斥体内部的基本知识,我只希望您将使用一个依赖于内核和下面的硬件的实现。 这些将是最可靠的。 (如果硬件支持这些)。如果你正在使用的互斥锁在这个内核/硬件级别上不起作用,那么它仍然是可靠的,但是我build议不要使用它,除非没有别的办法。
据我所知,Windows,Linux和.NET都将在内核/硬件层面使用互斥锁。
我已经链接到的维基百科页面解释了更多关于内部逻辑和可能的实现。 优选地,互斥体由硬件控制,从而使得互斥体的整个获取/设置成为不可分割的步骤 。 (只是为了确保系统不会在中间切换任务。)
Interlocked.CompareExchange
足以实现自旋锁。 虽然这很难做到。 乔·达菲的博客请参阅有关微妙的例子。
我使用了Reflector.NET来反编译System.Threading.ReaderWriterLockSlim
的源代码,该源代码被添加到最新版本的.NET框架中。
它主要使用Interlocked.CompareExchange
, Thread.SpinWait
和Thread.Sleep
来实现同步。 在某些情况下使用了一些EventWaitHandle
(内核对象)实例。
添加一些复杂性来支持单线程的重入。
如果你对这个领域感兴趣,并且在.NET中工作(或者至less可以阅读),那么你可能会觉得这个课程是非常有趣的。