Я где-то читал, что издержки мьютекса не так уж и велики, потому что переключение контекста происходит только в случае конфликта.
Также известны Futexes в Linux.
То же самое действует в Windows? Является ли Critical Section более подходящей картой для мьютексов в Linux.
Из того, что я понял, критические разделы обеспечивают лучшую оптимальную производительность по сравнению с Mutex, так ли это для каждого случая?
Есть ли угловой случай, когда мьютексы быстрее, чем критическая секция в Windows.
Предположим, что только один процесс-потоки получают доступ к мьютексам (просто чтобы исключить другое преимущество критических секций)
Добавлена информация: ОС Windows Server,
Язык С ++
Учитывая конкретную цель Critical Sections
а также Mutexes
Я не думаю, что вы можете задать вопрос относительно стоимости, так как у вас нет особой альтернативы, когда вам нужно, чтобы несколько потоков касались одних и тех же данных. Очевидно, что если вам просто нужно увеличить / уменьшить число, вы можете использовать Interlocked*()
функции на volatile
номер, и ты в порядке. Но для чего-то более сложного вам нужно использовать объект синхронизации.
Начните читать здесь, на Объекты синхронизации доступны в Windows ^. Все функции перечислены там, красиво сгруппированы и правильно объяснены. Некоторые из них только для Windows 8.
Что касается вашего вопроса, Critical Sections
дешевле, чем Mutexe
Так как они предназначены для работы в одном и том же процессе. Читать это ^ а также это ^ или просто следующая цитата.
Объект критической секции обеспечивает синхронизацию, аналогичную объекту мьютекса, за исключением того, что критическая секция может использоваться только потоками одного процесса. Объекты событий, мьютексов и семафоров также можно использовать в однопроцессном приложении, но объекты критических секций обеспечивают несколько более быстрый и эффективный механизм для синхронизации взаимного исключения (специфичные для процессора тесты и команды set). Как и объект мьютекса, объект критической секции может одновременно принадлежать только одному потоку, что делает его полезным для защиты общего ресурса от одновременного доступа. В отличие от объекта мьютекса, невозможно определить, был ли удален критический раздел.
я использую Critical Sections
для синхронизации того же процесса и Mutexes
для межпроцессной синхронизации. Только когда мне ДЕЙСТВИТЕЛЬНО нужно знать, был ли оставлен объект синхронизации, я использую мьютексы в том же процессе.
Итак, если вам нужен объект синхронизации, вопрос не в том, каковы затраты, а в том, что дешевле 🙂 На самом деле альтернативы нет, кроме повреждения памяти.
PS: Там могут быть альтернативы, такие как один упомянутый в выбранном ответе здесь ^ но я всегда обращаю внимание на функциональность, характерную для основной платформы, и на кроссплатформенность. Это всегда быстрее! Так что если вы используете Windows, используйте инструменты Windows 🙂
ОБНОВИТЬ
Исходя из ваших потребностей, вы можете уменьшить потребность в синхронизации объектов, пытаясь выполнить как можно больше автономной работы в потоке и объединять данные только в конце или время от времени.
Глупый Пример: Возьмите список URL. Вы должны очистить их и проанализировать их.
Таким образом, затраты можно снизить, выбрав правильный инструмент и подумав, как опустить и разблокировать замок. Но расходы не могут быть удалены 🙂
PSЯ думаю только в URL 🙂
ОБНОВЛЕНИЕ 2:
Нужно было в проекте сделать некоторые измерения. И результаты были довольно удивительными:
std::mutex
самый дорогой (цена кроссплатформенности)Mutex
в 2 раза быстрее чем std
,Critical Section
в 2 раза быстрее, чем родные Mutex
.SlimReadWriteLock
составляет + -10% от Critical Section
.InterlockedMutex
(Спинлки) в 1,25x — 1,75 раза быстрее, чем Critical Section
.Используя std :: mutex в Windows 8, я обычно получаю ускорение в 3-4 раза (в неконкурентном случае), используя свой собственный спин-блокировку:
на основе мьютекса
auto time = TimeIt([&]() {
for (int i = 0; i < tries; i++) {
bool val = mutex.try_lock();
if (val) {
data.value = 1;
}
}
});
самодельный замок бесплатно
time = TimeIt([&]() {
for (int i = 0; i < tries; i++) {
if (!guard.exchange(true)) {
// I own you
data.value = 1;
guard.store(true);
}
}
});
Тесты сделаны на x86.
Я не понял, что std :: mutex использует подчеркивание на окнах, потому что он генерирует много кода.