我想知道Mutex对象是忙于等待还是上下文切换(例如,拥有互斥锁的线程进入休眠状态,并在以后被中断唤醒),还是依赖于体系结构(即,您的计算机具有的内核数) ?我希望它实际上可以进行上下文切换。先感谢您。

最佳答案

从这里可以得出一个很好的答案:When should one use a spinlock instead of a mutex?

答案是,这取决于。 .Net中的Mutex类通常由操作系统支持,因为它是一个可以在多个进程之间共享的锁。它不打算仅在单个过程中使用。

这意味着我们受操作系统实现的支配。包括Windows在内的大多数现代OS都为多核计算机实现了自适应互斥体。

从以上答案中我们可以了解到,通过挂起线程来实现锁定通常非常昂贵,因为它至少需要2个上下文切换。在多核系统上,我们可以通过尝试先进行自旋等待来获取锁来避免某些上下文切换-如果锁竞争激烈,那么您很可能会在自旋等待中获取锁,因此永远不会受到惩罚上下文切换/线程挂起。如果在发生spinwait时超时到期,则锁将降级为全线程挂起,以防止浪费过多的cpu。

在单核计算机上,这没有任何意义,因为在锁持有人等待运行以完成释放锁所需的工作的同时,您只是在燃烧CPU。单核计算机上不使用自适应锁。

因此,要直接回答您的问题-Mutex类可能会同时做这两个事情-它会短暂等待(旋转等待)一会儿,以查看它是否可以在不执行上下文切换的情况下获取互斥体,以及是否可以不能在允许的短时间内这样做,它会挂起线程。重要的是要注意,等待时间通常很短,并且总体而言,该策略可以显着减少CPU总使用率或提高整体锁吞吐量。因此,即使我们正在消耗CPU的旋转等待时间,我们也可能总体上节省更多的CPU。

在.Net的上下文中,Mutex类提供互斥,但要在多个进程之间使用,因此往往很慢。具体来说,在Microsoft .Net Framework中Mutex类的实现,.Net Mutex类使用Win32 Mutex object

请注意,具体细节可能会根据您所使用的.Net的实现方式以及所使用的操作系统而有所不同。我试图提供以.Net/Microsoft/Windows为中心的主题处理方法,因为这是最常见的情况。

顺便说一句,如果只需要在单个进程中进行锁定,则应改用Monitor class或其关键字 lock 。信号量也存在类似的二分法- Semaphore 类最终由操作系统实现-它可用于进程间的通信,因此往往很慢。 SemaphoreSlim 类是在.Net中本地实现的,只能在单个进程中使用,并且往往更快。关于这一点,要阅读的一篇不错的msdn文章是Overview of Synchronization Primitives

09-10 03:58
查看更多