Подтвердить что ты не робот

Мьютексы действительно медленнее?

Я читал так много раз, здесь и всюду в сети, что мьютексы медленнее, чем критические секции/семафоры/insert-your-preferred-synchronization-method-here. но я никогда не видел ни бумаги, ни исследования, ни того, чтобы поддержать это утверждение.

Итак, откуда эта идея? это миф или реальность? мьютексы действительно медленнее?

4b9b3361

Ответ 1

В книге "Многопоточное приложение в win32" Джима Бевериджа и Роберта Винера говорится: "Требуется почти 100 раз дольше, чтобы заблокировать недописанный мьютекс, чем он блокирует незаслуженную критическую секцию, потому что критический раздел может быть выполнен в пользовательский режим без участия ядра"

И на msdn здесь в нем говорится, что "объекты критического раздела обеспечивают немного более быстрый и эффективный механизм синхронизации взаимного исключения"

Ответ 2

Я не считаю, что любой из ответов затрагивает ключевой момент того, почему они разные.

Мьютексы находятся на уровне операционной системы. Именованный мьютекс существует и доступен из ЛЮБОГО процесса в операционной системе (если его ACL разрешает доступ ко всем).

Критические разделы быстрее, так как они не требуют системного вызова в режиме ядра, однако они будут работать только WITHIN, вы не сможете заблокировать несколько процессов с использованием критического раздела. Поэтому, в зависимости от того, чего вы пытаетесь достичь и как выглядит ваш дизайн программного обеспечения, вы должны выбрать наиболее подходящий инструмент для работы.

Я дополнительно укажу вам, что Семафоры отделены от мьютексов/критических разделов из-за их подсчета. Семафоры могут использоваться для управления множественным параллельным доступом к ресурсу, где, когда мьютекс/критический раздел либо обращается, либо не получает доступа.

Ответ 3

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: быстрый поиск/выпуск для незанятых регионов, но потраченные впустую циклы для принадлежащих разделов.

Ответ 4

Да, критические разделы более эффективны. Для очень хорошего объяснения получите "Параллельное программирование в Windows".

В двух словах: мьютекс - это объект ядра, поэтому всегда есть контекстный переключатель, когда вы его приобретаете, даже если это "бесплатно". Критический раздел может быть приобретен без контекстного переключателя в этом случае, и (на многоядерной/процессорной машине) он даже начнет вращаться несколько циклов, если он заблокирован, чтобы предотвратить дорогостоящий переключатель контекста.

Ответ 5

Мьютекс (по крайней мере, в окнах) позволяет синхронизировать между различными процессами в дополнение к потокам. Это означает, что для обеспечения этого необходимо сделать дополнительную работу. Кроме того, поскольку Брайан указал, использование мьютекса также требует перехода в режим "ядро ​​", что приводит к еще одному удару по скорости (я считаю, то есть вывод, что ядро требуется для этой межпроцессной синхронизации, но у меня нет ничего, чтобы поддержать меня в этом).

Изменить: вы можете найти явную ссылку на межпроцессную синхронизацию здесь и для получения дополнительной информации по этой теме, посмотрите Синхронизация между процессами