Что на самом деле делают мьютекс и семафор? - PullRequest
9 голосов
/ 24 февраля 2012

Я хочу получить разъяснения по поводу мьютекса и семафора.
Мой вопрос:

  1. Что на самом деле делает мьютекс, когда поток пытается войти в область, заблокированную мьютексом, а. он ждет, когда будет снята блокировка? или б. он идет спать, пока замок не будет снят. В таком случае как снова проснуться при снятии блокировки?
  2. Тот же вопрос, что и 1, но в данном случае это семафор.
  3. Можете ли вы дать мне некоторый код относительно ожидания ожидания в pthread в C, а также случая, когда поток переходит в режим ожидания вместо ожидания? означает ли сон, что он заблокирован, или сон - это другой вид занятого ожидания?
  4. Я хочу знать некоторые программы, в которых описываются эти ситуации, например, некоторые исходные коды c, в которых реализовано ожидание, блокировка и т. Д.

Ответы [ 6 ]

6 голосов
/ 24 февраля 2012

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

То же самое относится и к семафору, за исключением того, что оно блокируется только в том случае, если счет уменьшается до нуля, а потоки пробуждаются только при увеличении счетчика выше нуля.

Оживленное ожидание - это когда вы не блокируетесь и не спите, ожидая чего-то, а постоянно проводите опрос в цикле, поэтому процессор всегда занят, но не делает ничего полезного.

Чтобы действительно достичь занятого ожидания, вам нужна атомарная переменная, но потоки POSIX не предоставляют такой возможности, поэтому вы не можете действительно написать занятое ожидание в pthreads. Самое близкое, что вы можете получить, это заблокировать мьютекс, прочитать флаг, разблокировать мьютекс, выполнить цикл, если флаг не был установлен. Это многократно блокирует и разблокирует мьютекс, но не ожидает готовности данных. В этой ситуации вы должны вместо этого использовать условную переменную.

Как правило, вы говорите, что поток спит, если он вызвал что-то вроде usleep, чтобы приостановить собственное выполнение на определенный период времени. Это в отличие от блокировки, когда он ожидает определенного сигнала, который будет предоставлен другим потоком.

4 голосов
/ 05 июля 2014

Пожалуйста, посмотрите на: https://stackoverflow.com/a/24582076/3163691

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

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

спящих этих потоков заканчивается, когда поток, которому принадлежит объект , освобождает его.

[ Планировщик ОС не дает никакого выполнения срез до спящих потоков ].

Сравните это с блокировкой & spinlock , где поток находится в состоянии ожидания "зацикливание / занятость", тратя драгоценное время ЦП и почти ничего . Поэтому в коде пользователя следует избегать spinlocks . Используйте взамен критическую секцию , mutex или семафор !.

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

Представьте себе мьютекс как блокировку , которая позволяет владеть только одним потоком . И что он имеет много безопасных атрибутов (владение, уведомление о прекращении, рекурсия и т. Д.).

И представьте себе семафор как блокировку , которая позволяет просто указанному количеству потоков владеть им. Тем не менее, он не имеет много полезных атрибутов mutex .

Надеюсь, это поможет.

0 голосов
/ 24 февраля 2012

Ожидание, сон, блокирование, все означают одно и то же:

  1. Поток выполняет системный вызов (получить мьютекс или семафор, подождать какое-то время, что угодно)

  2. ОС берет на себя управление, запускает планировщик, помечает поток как ожидающий ресурс, обновляет состояние других потоков, а затем передает управление потоку, который готов к запуску. Если более одного потока готово к запуску, один выбирается в соответствии с политикой планирования.

  3. Как только ресурс становится доступным (с помощью другого системного вызова, сделанного другим потоком), планировщик обновляет состояние предыдущего потока с момента ожидания готовности ресурса к запуску, и поток получает управление как только политика планировщика примет такое решение.

Пока поток ожидает ресурс, он не потребляет ЦП. Со своей стороны опрос не проводится.

0 голосов
/ 24 февраля 2012
  1. Что фактически делает мьютекс, когда поток пытается войти в область, заблокированную мьютексом, a.он ждет, когда будет снята блокировка?или б.он идет спать, пока замок не будет снят.В таком случае, как он снова просыпается при снятии блокировки?

Когда поток пытается получить блокировку мьютекса, он застревает и возвращается только в том случае, если ему предоставлена ​​блокировка.нить.Блокировка распознается ОС, поэтому ОС знает, что пока такая блокировка не станет доступной для потока, ей больше нечего делать.Поток припаркован внутри ОС.Только ОС знает, что теперь у потока есть право собственности, и он возвращается в спящий режим.В системе с одним ЦП, в этом самом случае, если включен какой-то другой процесс, блокировка мьютекса вернется только тогда, когда у потока есть оба - и ЦП, и блокировка предоставлена!

Примечание: когда вы делаете fwrite или select, происходит то же самое.Поскольку ОС знает, что соответствующий ввод-вывод займет время, поток становится бездействующим.Когда данные поступают, поток становится работоспособным.

  1. Тот же вопрос, что и 1, но в данном случае это семафор.Можете ли вы дать мне некоторый код относительно занятого ожидания в pthread в C, а также случая, когда поток переходит в режим ожидания вместо ожидания?означает ли сон, что он заблокирован или сон - это еще один вид ожидания занятости?

В обоих случаях НЕТ ожидания ожидания.Если кто-то захочет подождать, чтобы убить время, пока вы не получите блокировку - вы фактически потерпели неудачу с целью блокировки!Подумайте об этом, допустим, у нас строго один процессор (и глупая ОС).Итак, что происходит, поток 1 пытается получить блокировку, так как блокировка лежит на потоке B, так что поток A начинает делать занятое ожидание.Следовательно, ЦП никогда не освобождается из потока А, а поток В никогда не получает возможности выполнить на ЦП - в конце оба потока оказываются в бесполезной ситуации.Блокировки ничего не делают с объектом потока.Но процесс блокировки всегда паркует нити

0 голосов
/ 24 февраля 2012

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

Мьютексы обычно предназначены для однопотокового входа за раз (хотя они могут поддерживать рекурсивный ввод одним и тем же потоком).Семафоры, с другой стороны, допускают только n потоков одновременно, чтобы попытаться получить его (см. Эту MSDN запись или эту сравнительную запись Intel).

Спящий поток обычно означает, что он отказывается от своего временного интервала вычисления распределения, пока он не будет готов к пробуждению, и планировщик ОС не даст ему еще один временной интервал.лучшие примеры, которые вы, вероятно, найдете, будут на самом деле в исходных текстах ядра Linux (или любой другой ОС с открытым исходным кодом).

0 голосов
/ 24 февраля 2012

Говоря простыми словами, Mutex предназначен для вещей, когда вас интересует 1 блокировка .... Семафор предназначен для нескольких блокировок .. Я постараюсь выслать вам образцы.Я помню, что у меня были некоторые задания, связанные с семафором и мьютексом в C .. Что касается концепции, то здесь что-то смешное http://geekswithblogs.net/shahed/archive/2006/06/09/81268.aspx:)

Спасибо

...