windows 互斥锁真的更慢吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1666653/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:22:44  来源:igfitidea点击:

Are mutexes really slower?

windowsmultithreadingmutex

提问by Adrien Plisson

I have read so many times, here and everywhere on the net, that mutexes are slower than critical section/semaphores/insert-your-preferred-synchronisation-method-here. but i have never seen any paper or study or whatever to back up this claim.

我在这里和网上的任何地方都读过很多次,互斥锁比临界区/信号量/在此处插入您的首选同步方法要慢。但我从未见过任何论文或研究或任何东西来支持这一说法。

so, where does this idea come from ? is it a myth or a reality ? are mutexes really slower ?

那么,这个想法从何而来?这是神话还是现实?互斥锁真的更慢吗?

采纳答案by Mick

In the book "Multithreading application in win32" by Jim Beveridge and Robert Wiener it says: "It takes almost 100 times longer to lock an unowned mutex than it does to lock an unowned critical section because the critical section can be done in user mode without involving the kernel"

在 Jim Beveridge 和 Robert Wiener 所著的“Win32 中的多线程应用程序”一书中,它说:“锁定一个无主互斥锁比锁定一个无主临界区所需的时间几乎要长 100 倍,因为临界区可以在用户模式下完成而无需涉及内核”

And on msdn hereit says "critical section objects provide a slightly faster, more efficient mechanism for mutual-exclusion synchronization"

在 msdn 上它说“临界区对象为互斥同步提供了一种稍微更快、更有效的机制”

回答by Spence

I don't believe that any of the answers hit on the key point of why they are different.

我不相信任何答案都触及了为什么它们不同的关键点。

Mutexes are at operating system level. A named mutex exists and is accessible from ANY process in the operating system (provided its ACL allows access from all).

互斥体位于操作系统级别。一个命名的互斥锁存在并且可以从操作系统中的任何进程访问(前提是它的 ACL 允许从所有进程访问)。

Critical sections are faster as they don't require the system call into kernel mode, however they will only work WITHINa process, you cannot lock more than one process using a critical section. So depending on what you are trying to achieve and what your software design looks like, you should choose the most appropriate tool for the job.

关键的部分是更快它们不需要系统调用到内核模式,但是他们只会工作WITHIN一个过程,你不能用一个关键部分锁定多个进程。因此,根据您要实现的目标以及软件设计的外观,您应该选择最适合该工作的工具。

I'll additionally point out to you that Semaphores are separate to mutex/critical sections, because of their count. Semaphores can be used to control multiple concurrent access to a resource, where as a mutex/critical section is either being accessed or not being accessed.

我还要向您指出,信号量与互斥量/临界区分开,因为它们的数量。信号量可用于控制对资源的多个并发访问,其中互斥锁/临界区要么被访问,要么不被访问。

回答by Christopher

A CRITICAL_SECTION is implemented as a spinlock with a capped spin count. See MSDN InitializeCriticalSectionAndSpinCountfor the indication of this.

CRITICAL_SECTION 实现为具有上限自旋计数的自旋锁。有关这一点的指示,请参阅MSDN InitializeCriticalSectionAndSpinCount

When the spin count 'elapsed', the critical section locks a semaphore (or whatever kernel-lock it is implemented with).

当自旋计数“过去”时,临界区锁定一个信号量(或任何实现它的内核锁)。

So in code it works like this (not really working, should just be an example) :

所以在代码中它是这样工作的(不是真的工作,应该只是一个例子):

CRITICAL_SECTION s;

void EnterCriticalSection( CRITICAL_SECTION* s )
{
    int spin_count = s.max_count;
    while( --spin_count >= 0 )
    {
        if( InterlockedExchange( &s->Locked, 1 ) == 1 )
        {
           // we own the lock now
           s->OwningThread = GetCurrentThread();
           return;
        }
    }
    // lock the mutex and wait for an unlock
    WaitForSingleObject( &s->KernelLock, INFINITE );
}

So if your critical section is only held a very short time, and the entering thread does only wait very few 'spins' (cycles) the critical section can be very efficient. But if this is not the case, the critical section wastes many cycles doing nothing, and then falls back to a kernel synchronization object.

因此,如果您的临界区只保持很短的时间,并且进入的线程只等待很少的“旋转”(周期),临界区可能会非常有效。但如果不是这种情况,临界区会浪费许多周期无所事事,然后回退到内核同步对象。

So the tradeoff is :

所以权衡是:

Mutex: Slow acquire/release, but no wasted cycles for long 'locked regions'

互斥体:缓慢获取/释放,但不会浪费长“锁定区域”的周期

CRITICAL_SECTION: Fast acquire/release for unowned 'regions', but wasted cycles for owned sections.

CRITICAL_SECTION:快速获取/释放未拥有的“区域”,但浪费了拥有部分的周期。

回答by Niki

Yes, critical sections are more efficient. For a very good explanation, get "Concurrent Programming on Windows".

是的,临界区效率更高。有关非常好的解释,请参阅“Windows 上的并发编程”。

In a nutshell: a mutex is a kernel object, so there is always a context switch when you acquire one, even if "free". A critical section can be acquired without a context switch in that case, and (on an multicore/processor machine) it will even spin a few cycles if it's blocked to prevent the expensive context switch.

简而言之:互斥体是一个内核对象,所以当你获得一个时,总会有一个上下文切换,即使是“免费”的。在这种情况下,可以在没有上下文切换的情况下获取临界区,并且(在多核/处理器机器上)如果它被阻止以防止昂贵的上下文切换,它甚至会旋转几个周期。

回答by Grant Peters

A mutex (at least in windows) allows for synchronizations between different processesin addition to threads. This means extra work must be done to ensure this. Also, as Brian pointed out, using a mutex also requires a switch to "kernel" mode, which causes another speed hit (I believe, i.e. infer, that the kernel is required for this interprocess synchronization, but I've got nothing to back me up on that).

互斥体(至少在 Windows 中)允许除线程之外的不同进程之间进行同步。这意味着必须做额外的工作来确保这一点。此外,正如布赖恩指出的那样,使用互斥锁还需要切换到“内核”模式,这会导致另一个速度下降(我相信,即推断,此进程间同步需要内核,但我没有什么可支持的我在那个)。

Edit: You can find explicit reference to interprocess synchronization hereand for more info on this topic, have a look at Interprocess Synchronization

编辑:您可以在此处找到对进程间同步的显式参考,有关此主题的更多信息,请查看进程间同步