Что на самом деле делают мьютекс и семафор?

Мне нужно уточнение относительно мьютекса и семафора. Мой вопрос:

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

Ответ 1

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

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

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

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

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

Ответ 2

Пожалуйста, взгляните на: fooobar.com/questions/26212/...

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

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

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

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

Контрастируйте его с помощью блокировки и спин-блокировки, где поток находится в состоянии "ожидание цикла", тратя драгоценное процессорное время, делая почти ничего. Поэтому в коде пользователя следует избегать spinlocks. Используйте критический раздел, мьютекса или семафор!.

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

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

И подумайте о семафоре как lock, который позволяет просто указать указанное количество потоков. Однако он не содержит много полезных атрибутов мьютекса.

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

Ответ 3

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

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

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

Ответ 4

  • Какие мьютексы действительно делают, когда поток пытается войти в область, заблокированную мьютексом, a. он ждет, когда замок будет выпущен? или b. это идет к до тех пор, пока замок не будет отпущен. В этом случае, как он снова проснется когда блокировка отпущена?

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

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

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

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

Ответ 5

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

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

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

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

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

Ответ 6

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

Спасибо