Учитывая конкретную цель Critical Sections
и Mutexes
, я не думаю, что вы можете задать вопрос относительно стоимости, поскольку у вас нет большой альтернативы, когда вам нужно несколько потоков, затрагивающих одни и те же данные. Очевидно, что если вам просто нужно увеличить/уменьшить число, вы можете использовать функции Interlocked*()
для числа volatile
, и все готово. Но для чего-то более сложного вам нужно использовать объект синхронизации.
Начните чтение с объектов синхронизации, доступных в Windows^ а>. Все функции перечислены там, красиво сгруппированы и правильно объяснены. Некоторые только для Windows 8.
Что касается вашего вопроса, Critical Sections
дешевле, чем Mutexe
, поскольку они предназначены для работы в одном и том же процессе. Прочтите это^ и это ^ или просто следующая цитата.
Объект критической секции обеспечивает синхронизацию, аналогичную той, которая обеспечивается объектом мьютекса, за исключением того, что критическая секция может использоваться только потоками одного процесса. Объекты событий, мьютексов и семафоров также могут использоваться в приложении с одним процессом, но объекты критической секции обеспечивают несколько более быстрый и эффективный механизм синхронизации с взаимоисключением (тестирование и установка для конкретных процессоров). Как и объект мьютекса, объект критической секции может одновременно принадлежать только одному потоку, что делает его полезным для защиты общего ресурса от одновременного доступа. В отличие от объекта мьютекса, невозможно определить, был ли заброшен критический раздел.
Я использую Critical Sections
для синхронизации одного и того же процесса и Mutexes
для синхронизации между процессами. Только когда мне ДЕЙСТВИТЕЛЬНО нужно знать, был ли заброшен объект синхронизации, я использую мьютексы в том же процессе.
Итак, если вам нужен объект синхронизации, вопрос не в стоимости, а в том, что дешевле :) На самом деле нет другой альтернативы, кроме повреждения памяти.
PS: могут быть альтернативы, такие как один упомянутый в выбранном ответе здесь^, но я всегда выбираю основные функции, специфичные для платформы, а не кросс-платформенность. Это всегда быстрее! Поэтому, если вы используете Windows, используйте инструменты Windows :)
ОБНОВЛЕНИЕ
В зависимости от ваших потребностей вы можете уменьшить потребность в объектах синхронизации, пытаясь выполнять как можно больше автономной работы в потоке и объединять данные только в конце или время от времени.
Глупый пример: Возьмите список URL-адресов. Вам нужно очистить их и проанализировать.
- Добавьте кучу потоков и начните выбирать URL-адреса один за другим из входного списка. Для каждого вашего процесса вы централизуете результаты по мере его выполнения. Это в реальном времени и круто
- Или вы можете добавить потоки, каждый из которых имеет часть входных URL-адресов. Это устраняет необходимость синхронизации процесса выбора. Вы сохраняете результат анализа в потоке и в конце объединяете результат только один раз. Или, скажем, только один раз каждые 10 URL-адресов. Не для каждого из них. Это значительно сократит количество операций синхронизации.
Таким образом, затраты можно снизить, выбрав правильный инструмент и подумав, как уменьшить количество блокировок и разблокировок. Но расходы убрать нельзя :)
PS: я думаю только об URL :)
ОБНОВЛЕНИЕ 2:
Была потребность в проекте, чтобы сделать некоторые измерения. И результаты были довольно неожиданными:
std::mutex
— самый дорогой. (цена кроссплатформенности)
- Собственный Windows
Mutex
в 2 раза быстрее, чем std
.
Critical Section
в 2 раза быстрее нативного Mutex
.
SlimReadWriteLock
составляет +-10% от Critical Section
.
- Мой самодельный
InterlockedMutex
(спин-блокировка) в 1,25-1,75 раза быстрее, чем Critical Section
.
person
CodeAngry
schedule
06.08.2013