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




multithreading synchronization (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. Вы можете так сказать, но обратите внимание, что они используются в разных случаях. Не заменяйте один на другой, даже если вы можете это сделать.


В то время как ответ @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 для дальнейших объяснений


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


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

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

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

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


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

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

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

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

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

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

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

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

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


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

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

Разница между Mutex и Binary-Semaphore - это принцип собственности:

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

Caveat: Я написал «позволяет», если и как эти проблемы исправлены, зависит от реализации ОС.

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

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

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

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

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

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

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


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

мьютекс:

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

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

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

Семафор:

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

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


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

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

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





semaphore