Adr*_*son 19 windows multithreading mutex
我已经阅读了很多次,无论是在网络上还是网络上,互斥体都比关键部分/信号量/插入你的首选同步方法慢.但我从未见过任何论文或研究或其他什么来支持这一主张.
那么,这个想法来自哪里?这是神话还是现实?互斥体真的慢吗?
Spe*_*nce 15
我不相信任何答案都会触及他们为什么不同的关键点.
互斥锁处于操作系统级别.存在一个已命名的互斥锁,可以从操作系统中的任何进程访问(前提是其ACL允许从所有进程访问).
关键的部分是更快它们不需要系统调用到内核模式,但他们只会工作WITHIN一个过程,你可以使用一个关键部分锁定超过一个过程.因此,根据您要实现的目标以及软件设计的外观,您应该选择最合适的工具.
我还要向你指出,信号量与互斥/关键部分是分开的,因为它们的数量.信号量可用于控制对资源的多个并发访问,其中正在访问或未访问互斥/临界区.
CRITICAL_SECTION实现为具有上限旋转计数的自旋锁.有关此信息,请参阅MSDN InitializeCriticalSectionAndSpinCount.
当旋转计数'过去'时,临界区锁定一个信号量(或者它实现的任何内核锁).
所以在代码中它的工作原理是这样的(不是真的有效,应该只是一个例子):
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 );
}
Run Code Online (Sandbox Code Playgroud)
因此,如果您的关键部分只保持很短的时间,并且进入的线程只等待很少的"旋转"(周期),那么关键部分可以非常有效.但如果不是这种情况,那么关键部分会浪费许多循环,什么都不做,然后又回退到内核同步对象.
所以权衡是:
Mutex:缓慢获取/释放,但长期"锁定区域"没有浪费周期
CRITICAL_SECTION:快速获取/释放无主区域,但浪费了自有区域的周期.