互斥体是如何实现的?

sta*_*tti 55 language-agnostic concurrency mutex

对于特定应用,某些实现是否优于其他实现?推出自己的产品有什么收获吗?

Ada*_*ski 31

查看维基百科上的测试和设置机器指令的描述,其中提到了如何在机器级别实现原子操作.我可以想象大多数语言级互斥实现都依赖于机器级支持,例如Test-and-set.


Dav*_*ner 23

在亚当斯基的建设test-and-set建议,你也应该看看"快速用户空间互斥体"或概念futexes的.

Futexes具有理想的属性,在锁定或解锁无争用互斥锁的常见情况下,它们不需要内核系统调用.在这些情况下,用户模式代码成功使用原子比较和交换(CAS)操作来锁定或解锁互斥锁.

如果CAS失败,则互斥锁是争用的,并且sys_futex必须使用Linux下的内核系统调用来等待互斥锁(在锁定情况下)或唤醒其他线程(在解锁情况下).

如果你真的想要自己实现这个,请确保你也阅读了Ulrich Drepper的论文.


Wim*_*ink 10

互斥优选地在操作系统的内核中运行,同时保持的代码量在其周围尽可能短,所以可以避免被切断而任务切换到另一个进程.因此,确切的实施是一个秘密.虽然这并不复杂.它基本上是一个具有布尔字段的对象,它可以获取和设置.

  • 使用计数器时,它可以成为信号量.
  • 互斥锁是关键部分的起点,它在内部使用互斥锁来查看它是否可以输入一段代码.如果互斥锁是空闲的,它会设置互斥锁并执行代码,仅在完成时释放互斥锁.当关键部分注意到互斥锁被锁定时,它可以等待释放互斥锁.

在基本的互斥逻辑周围有包装器将它包装在一个对象中.然后有更多的包装器对象使它在内核之外可用.然后是另一个使它在.NET中可用的包装器.然后,一些程序员将根据自己的逻辑需求编写自己的包装代码.包装纸周围的包装纸真的让它们变得模糊不清.

现在,有了关于互斥体内部的基本知识,我希望你将使用一个依赖于内核和下面硬件的实现.这些将是最可靠的.(如果硬件支持这些.)如果您使用的互斥锁在此内核/硬件级别不起作用,那么它仍然可靠但我建议不要使用它,除非别无选择.

据我所知,Windows,Linux和.NET都将在内核/硬件级别使用互斥锁.

我链接到的维基百科页面解释了有关内部逻辑和可能实现的更多信息.优选地,互斥体由硬件控制,从而使得互斥体的整体获取/设置成为不可分割的步骤.(只是为了确保系统不会在中间切换任务.)

  • 真是的 那是我八年前写的!:)但是,这是一个秘密,因为没有人真正检查Linux内核中互斥量的源代码。而那些检查它的人通常会发现解密它背后的逻辑很困难。有关Linux中Mutex代码的信息,请参见https://github.com/torvalds/linux/blob/master/kernel/locking/mutex.c ...幸运的是,它得到了很好的评论。仍然很复杂。如我所说,*有点*秘密... (2认同)