Когда мы должны использовать мьютекс и когда следует использовать семафор

Когда мы должны использовать мьютекс и когда мы должны использовать семафор?

Ответ 1

Вот как я помню, когда использовать что -

Семафор: Используйте семафор, когда вы (нить) хотите спать, пока какой-либо другой поток не попросит вас проснуться. Семафор "вниз" происходит в одном потоке (продюсер) и семафор "вверх" (для того же семафора) происходит в другом потоке (потребителе) Например: в случае проблемы производителя-потребителя производитель хочет спать до тех пор, пока по меньшей мере один буферный слот не будет пустым - только потребительский поток может определить, когда буферный слот пуст.

мьютекса: Используйте мьютекс, когда вы (поток) хотите выполнить код, который не должен выполняться каким-либо другим потоком одновременно. Mutex 'down' происходит в одном потоке, и mutex 'up' должен произойти в том же потоке позже. Например: если вы удаляете node из глобального связанного списка, вы не хотите, чтобы другой поток галстук с указателями, когда вы удаляете node. Когда вы приобретаете мьютексы и заняты удалением node, если другой поток пытается получить один и тот же мьютекс, он будет спать до тех пор, пока вы не отпустите мьютекс.

SpinLock: Используйте спин-блокировку, когда вы действительно хотите использовать мьютекс, но ваш поток не разрешается спать. Например: обработчик прерываний в ядре ОС никогда не должен спать. Если это произойдет, система замерзнет/сработает. Если вам нужно вставить node в глобально разделенный связанный список из обработчика прерываний, приобретите спин-блокировку - вставьте node - отключаемую спин-блокировку.

Ответ 2

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

Можно считать эквивалентным нормальному счетному семафору (со счетом 1) и требованию, чтобы он мог быть выпущен только тем же потоком, который заблокировал его (a).

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

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

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

Эквивалентные операции:

Counting semaphore          Mutual exclusion semaphore
--------------------------  --------------------------
  Claim/decrease (P)                  Lock
  Release/increase (V)                Unlock

Кроме того: в случае, если вы когда-либо задумывались над причудливыми письмами, используемыми для утверждения и выпуска семафоров, это потому, что изобретатель был голландцем. Probeer te verlagen означает попробовать и уменьшить, в то время как verhogen означает увеличить.


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

Ответ 3

Очень важно понять, что мьютекс не семафор со счетом 1!

Вот почему есть такие вещи, как бинарные семафоры (которые действительно являются семафорами со счетом 1).

Различие между Mutex и двоичным-семафором - это принцип собственности:

Мьютекс приобретается заданием и поэтому также должен быть выпущен той же задачей. Это позволяет исправить несколько проблем с двоичными семафорами (Accidential release, рекурсивный тупик и инверсия приоритета).

Предостережение: я написал "делает возможным", если и как эти проблемы исправлены, зависит от реализации ОС.

Поскольку мьютекс должен быть выпущен одной задачей, он не очень хорош для синхронизации задач. Но в сочетании с переменными состояния вы получаете очень мощные строительные блоки для создания всех типов примитивов ipc.

Итак, моя рекомендация: если вы получили чисто реализованные мьютексы и переменные условия (например, с POSIX pthreads), используйте их.

Используйте семафоры только в том случае, если они точно соответствуют задаче, которую вы пытаетесь решить, не пытайтесь создавать другие примитивы (например, rw-locks из семафоров, использовать мьютексы и переменные условия для них)

Существует много недоразумений мьютексов и семафоров. Лучшее объяснение, которое я нашел до сих пор, содержится в этой статье из трех частей:

Мьютекс против семафоров - Часть 1: Семафоры

Mutex vs. Семафоры - Часть 2: Мьютекс

Мьютекс против семафоров - часть 3 (заключительная часть): проблемы взаимного исключения

Ответ 4

В то время как ответ @opaxdiablo полностью правильный, я хотел бы указать, что сценарий использования обеих вещей совершенно другой. Мьютекс используется для одновременной защиты некоторых частей кода, семафоры используются для одного потока, чтобы сигнализировать о запуске другого потока.

/* Task 1 */
pthread_mutex_lock(mutex_thing);
    // Safely use shared resource
pthread_mutex_unlock(mutex_thing);



/* Task 2 */
pthread_mutex_lock(mutex_thing);
   // Safely use shared resource
pthread_mutex_lock(mutex_thing);

Сценарий семафора отличается:

/* Task 1 - Producer */
sema_post(&sem);   // Send the signal

/* Task 2 - Consumer */
sema_wait(&sem);   // Wait for signal

См. http://www.netrino.com/node/202 для дальнейших объяснений

Ответ 5

См. "Пример туалета" - http://pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm:

мьютекса:

Является ключом к туалету. Один человек может иметь ключ - занимать туалет - в то время. По завершении, человек дает (освобождает) ключ к следующему человеку в очереди.

Официально: "Мьютексы обычно используются для сериализации доступа к разделу кода повторного входа, который не может выполняться одновременно более чем одним потоком. Объект mutex разрешает только один поток в контролируемый раздел, заставляя другие потоки пытаться получите доступ к этому разделу, чтобы дождаться выхода первого потока из этого раздела". Ссылка: Библиотека разработчиков Symbian

(Мьютекс - действительно семафор со значением 1.)

Семафор:

Является ли количество свободных идентичных туалетных ключей. Например, у нас есть четыре туалета с одинаковыми замками и ключами. Счет семафора - количество ключей - устанавливается в начале 4 (все четыре туалета являются свободными), тогда значение счета уменьшается по мере поступления людей. Если все туалеты заполнены, то есть. свободных ключей нет, счет семафора равен 0. Теперь, когда уравнение один человек выходит из туалета, семафор увеличивается до 1 (один свободный ключ) и передается следующему человеку в очереди.

Официально: "Семафор ограничивает количество одновременных пользователей общего ресурса до максимального числа. Темы могут запрашивать доступ к ресурсу (уменьшая семафор) и могут сигнализировать, что они закончили использование ресурса (увеличивая семафор)". Ссылка: Библиотека разработчиков Symbian

Ответ 6

Попытка не казаться загадкой, но не может помочь себе.

В вашем вопросе должна быть разница между мьютексом и семафорами? И, быть более точным, должен быть вопрос: "Какова связь между мьютексом и семафорами?"

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

В терминологии объектов мы можем заметить, что:

1 Семафор содержит мьютекс

. Мьютекс - это не семафор, а семафор - не мьютекс.

Есть некоторые семафоры, которые будут действовать так, как если бы они были мьютеками, называемыми двоичными семафорами, но они не совершают ошибок mutex.

Существует специальный компонент Signaling (posix использует condition_variable для этого имени), необходимый для создания Semaphore из мьютекса. Подумайте об этом как источнике уведомлений. Если два или более потоков подписаны на тот же источник уведомлений, тогда можно отправить сообщение одному или одному, чтобы пробудиться.

Может существовать один или несколько счетчиков, связанных с семафорами, которые защищены мьютексом. Самый простой сценарий для семафора, есть один счетчик, который может быть либо 0, либо 1.

Вот где путаница льется, как муссонный дождь.

Семафор с счетчиком, который может быть 0 или 1, не является мьютексом.

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

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

  • Одиночный счетчик со значением 0 или 1 и сигнализацией, когда значение переходит в 1 И затем разблокирует одного из парней, ожидающего сигнала == Двоичный семафор

  • Одиночный счетчик со значением от 0 до N и сигнализацией, когда значение меньше N, и блокирует/ждет, когда значения N == Счетный семафор

  • Одиночный счетчик со значением от 0 до N и сигнализацией, когда значение переходит в N, и блокирует/ожидает, когда значения меньше N == Барьерный семафор (ну, если они не назовут его, тогда они должны.)

Теперь на ваш вопрос, когда использовать что. (ИЛИ довольно корректная версия вопроса .3 когда использовать мьютекс и когда использовать двоичный-семафор, поскольку нет никакого сравнения с не-двоичным-семафором.) Использовать мьютекс, когда 1. вам требуется индивидуальное поведение, которое не предоставляется бинарным семафором, например, блокировка спина или быстрая блокировка или рекурсивные блокировки. Обычно вы можете настроить мьютексы с атрибутами, но настройка семафора - это не что иное, как создание нового семафора. 2. вы хотите легкий или быстрый примитив

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

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

И, наконец, прочитал книгу, а не полагался только на SO.

Ответ 7

Я думаю, что вопрос должен быть разницей между мьютексом и двоичным семафором.

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

binary Semaphore = Это скорее механизм сигнала, любой другой поток с более высоким приоритетом, если хотите, чтобы он мог сигнализировать и принимать блокировку.

Ответ 8

Mutex предназначен для защиты общего ресурса.
Семафор должен отправлять потоки.

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


Семафор:
Представьте, что нам нужно сделать расчет, как показано ниже:

c = a + b;

Кроме того, нам нужна функция geta() для вычисления a, функции getb() для вычисления b и функции getc() для вычисления c = a + b.

Очевидно, что мы не можем выполнить c = a + b, если не были завершены geta() и getb().
Если три функции три потока, нам нужно отправить три потока.

int a, b, c;
void geta()
{
    a = calculatea();
    semaphore_increase();
}

void getb()
{
    b = calculateb();
    semaphore_increase();
}

void getc()
{
    semaphore_decrease();
    semaphore_decrease();
    c = a + b;
}

t1 = thread_create(geta);
t2 = thread_create(getb);
t3 = thread_create(getc);
thread_join(t3);

С помощью семафора приведенный выше код может гарантировать, что t3 не выполнит свою работу до тех пор, пока t1 и t2 не выполнит свои задания.

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

Ответ 9

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

Основные вещи, которые я видел семафоры со счетом, большим, чем один, используется для ситуаций с производителем/потребителем, в которых у вас есть очередь определенного фиксированного размера.

Тогда у вас есть два семафора. Первый семафор изначально устанавливается как количество элементов в очереди, а второй семафор установлен в 0. Производитель выполняет операцию P на первом семафоре, добавляет в очередь. и выполняет операцию V на втором. Потребитель выполняет операцию P на втором семафоре, удаляет из очереди, а затем выполняет операцию V на первом.

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

Ответ 10

Мьютекс - частный случай семафора. Семафор позволяет нескольким потокам перейти в критический раздел. При создании семафора вы определяете, как разрешить потоки в критическом разделе. Конечно, ваш код должен иметь возможность обрабатывать несколько обращений к этому критическому разделу.