2009-04-17 2 views
3

При каких обстоятельствах должен использоваться каждый из следующих объектов синхронизации?Когда должны использоваться все объекты синхронизации потоков?

  1. ReaderWriter блокировки
  2. Семафор
  3. мьютекса
+2

В моих глазах это * вопрос (название + список), просто спросил плохо. Для меня нет прямой причины закрыть, он мог бы, как и другие, отредактировать его более конкретно. – Gregor

+2

Этот «вопрос», очевидно, не имеет единого ответа, но он может определенно создать много очень интересного комментария. Например, как блокировки RW обычно менее эффективны, чем простые мьютексы. –

+2

Этот вопрос нужно переформулировать. Но это вопрос. Парень просит об использовании этих инструментов. Проголосовало заново – Quibblesome

ответ

5
  • Поскольку wait() будет возвращаться один раз для каждого вызова post(), семафоры являются базовой моделью производителя-потребителя - простейшей формой межпоточного сообщения, кроме ma ybe сигналов. Они используются так, что один поток может сообщить другому потоку, что что-то случилось, что его интересует (и сколько раз), и для управления доступом к ресурсам, которые могут иметь не более фиксированное конечное число пользователей. Они предлагают заказные гарантии, необходимые для многопоточного кода.

  • Мьютексы делают то, что говорят на олове - «взаимное исключение». Они гарантируют, что право доступа к некоторому ресурсу «удерживается» только по потоку за раз. Это дает гарантии атомарности и порядка, необходимые для многопоточного кода. В большинстве ОС они также предлагают разумно сложное поведение официанта, в частности, чтобы избежать инверсии приоритета.

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

  • ReaderWriter замки оптимизация над мьютексами, в тех случаях, когда у вас будет много споров, большинство доступов только для чтения, и одновременное чтение допустимы для структуры защищаемых данных. В таких случаях исключение требуется только в том случае, если речь идет о писателе - читателям не нужно исключать друг друга. Чтобы продвинуть читателя к писателю, все остальные читатели должны закончить (или прервать и начать ждать, чтобы повторить попытку, если они также хотят стать писателями) до того, как будет зафиксирована блокировка писателя. Блокировки ReaderWriter, вероятно, будут медленнее в тех случаях, когда они не ускоряются из-за дополнительного ведения бухгалтерского учета, выполняемого ими по мьютексам.

  • Переменные условия предназначены для того, чтобы потоки могли ожидать определенных фактов или комбинаций фактов, когда это условие более сложное, чем просто «оно было ткнуто», как для семафоров, или «никто его не использует» «для мьютексов и писательской части блокировок читателя-писателя, или« никакие авторы не используют его »для считывающей части блокировок считывателя-писателя. Они также используются там, где условие запуска отличается для разных ожидающих потоков, но зависит от какого-либо или всего одного состояния (места памяти или что-то еще).

  • Спин блокировки предназначены для того, чтобы вы ожидали очень короткого периода времени (например, несколько циклов) на одном процессоре или ядре, тогда как другое ядро ​​(или часть оборудования, такое как шина ввода/вывода) одновременно делает некоторые работы, о которых вы заботитесь. В некоторых случаях они дают повышение производительности по сравнению с другими примитивами, такими как семафоры или прерывания, но должны использоваться с особой осторожностью (поскольку алгоритмы блокировки сложны в современных моделях памяти) и только тогда, когда это необходимо (так как яркие идеи, чтобы избежать системных примитивов часто преждевременная оптимизация).

Btw, эти ответы не являются специфическими для C# (отсюда, например, комментарий о «большинстве ОС»).Ричард замечает, что в C# вы должны использовать простые старые блокировки, где это необходимо. Я считаю, что мониторы представляют собой пару переменных mutex/condition, свернутую в один объект.

1

Я бы сказал, каждый из них может быть "лучшим" - зависит от случая использования ;-)

1

Простой ответ: почти никогда.

Наилучший тип блокировки - не требуется блокировка (без общего измененного состояния).

Если вам нужна блокировка, попытайтесь использовать монитор (через заявление блокировки), если у вас есть конкретные потребности что-то другое (в этом случае см ответ Onebyone в

Кроме того, предпочитают ReaderWriteLockSlim к ReaderWriterLock (за исключением в крайне редком случае, требующем его справедливости).