Я использую сценарий постфиксации, подобный этому один .
Это, посылает хорошее электронное письмо HTML. Я обновил его некоторые, где это выделяет код, который был удален в красном и коде выделений, который был включен синий.
В книге Джима Бевериджа и Роберта Винера «Многопоточное приложение в win32» говорится: «Блокировка бесхозного мьютекса занимает почти в 100 раз больше времени, чем блокировка незарегистрированной критической секции, потому что критическая секция может быть выполнена в пользовательском режиме без участия ядра "
И в msdn здесь говорится, что" объекты критической секции обеспечивают немного более быстрый и эффективный механизм для синхронизации взаимного исключения "
Я не верю, что какой-либо из ответов касается ключевого момента, почему они отличаются.
Мьютексы находятся на уровне операционной системы. Именованный мьютекс существует и доступен из ЛЮБОГО процесса в операционной системе (при условии, что его ACL разрешает доступ всем).
Критические секции работают быстрее, поскольку они не требуют системного вызова в режиме ядра, однако они будут работать только ВНУТРИ процесса нельзя заблокировать более одного процесса с помощью критической секции. Поэтому в зависимости от того, чего вы пытаетесь достичь и как выглядит ваш программный дизайн, вы должны выбрать наиболее подходящий инструмент для работы.
Я дополнительно укажу вам, что семафоры отделены от мьютексов / критических разделов, потому что их подсчета. Семафоры можно использовать для управления множественным одновременным доступом к ресурсу, где в качестве мьютекса / критического раздела либо осуществляется доступ, либо нет доступа.
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 );
}
Итак, если ваша критическая секция удерживается очень короткое время, а входящий поток ждет только очень мало "вращений" (циклов) критической секции может быть очень эффективным. Но если это не так, критическая секция тратит много циклов, ничего не делая, а затем возвращается к объекту синхронизации ядра.
Итак, компромисс:
Мьютекс : Медленное получение / освобождение, но без потраченных впустую циклов для длинных «заблокированных областей»
CRITICAL_SECTION : Быстрое получение / освобождение для незанятых «регионов», но потраченные впустую циклы для принадлежащих разделов.
Да, критические секции более эффективны. Чтобы получить очень хорошее объяснение, прочтите «Параллельное программирование в Windows».
В двух словах: мьютекс - это объект ядра, поэтому при его получении всегда есть переключение контекста, даже если он «бесплатный». В этом случае критическая секция может быть получена без переключения контекста, и (на многоядерной / процессорной машине) она даже будет выполнять несколько циклов, если она заблокирована, чтобы предотвратить дорогостоящее переключение контекста.
Мьютекс (по крайней мере, в Windows) позволяет синхронизировать между различными процессами в дополнение к потокам. Это означает, что для этого необходимо проделать дополнительную работу. Кроме того, как Брайан указал , использование мьютекса также требует переключения в режим «ядра», что вызывает еще одно снижение скорости (я полагаю , т. Е. Предполагаю, что ядро требуется для эта межпроцессная синхронизация, но мне нечего подкрепить).
Изменить: вы можете найти явную ссылку на межпроцессную синхронизацию здесь , а для получения дополнительной информации по этой теме, посмотрите Межпроцессная синхронизация