2010-10-28 4 views
86

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

+2

Возможный дубликат [Что такое мьютексы и семафор в Java? В чем основное отличие?] (Http://stackoverflow.com/questions/771347/what-is-mutex-and-semaphore-in-java-what-is-the-main-difference) –

ответ

47

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

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

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

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

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

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

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

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


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

+0

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

+0

Понятно, что двоичный семафор _is_ является мьютеком, и он эквивалентен нормальному семафору с одним счетом.В реализации могут быть различия в реализации, например, эффективности или собственности на ресурс (может быть выпущен кем-то другим, кроме претендента, который я не согласен с BTW - ресурс должен быть доступен только для потока, который утверждал это). – paxdiablo

+1

Еще одна потенциальная разница в реализации - это рекурсивный мьютекс. Поскольку существует только один ресурс, одному потоку может быть разрешено блокировать его несколько раз (при условии, что он освобождает его много раз). Это не так просто с ресурсом нескольких экземпляров, так как вы можете не знать, хочет ли поток снова запрашивать экземпляр _another_ или экземпляр _same_. – paxdiablo

1

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

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

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

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

12

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

+2

Вы правы. Даже если вы используете семафор со счетом один, вы подразумеваете что-то о том, что делаете, чем если вы использовали мьютекс. – Omnifarious

+0

Я не уверен, что согласен с этим, хотя я не так категорично отказываюсь от того, что я сниму вас :-) Вы говорите, что шаблон использования семафоров заключается в уведомлении потоков, но это именно то, что делают мьютексы, когда есть другой поток ожидая на нем и точно, какие семафоры _don't_, когда в 'sema_wait' нет потоков :-) По-моему, они _both_ о ресурсах, а уведомление, переданное другим потокам, является побочным эффектом (очень важным, мудрый) защиты. – paxdiablo

+0

'Вы говорите, что шаблон использования семафоров должен уведомлять потоки Один вопрос об уведомлении потоков. Вы можете безопасно вызывать 'sem_post' из обработчика сигналов (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html), но не рекомендуется называть' pthread_mutex_lock' и 'pthread_mutex_unlock' из обработчиков сигналов (http://manpages.ubuntu.com/manpages/lucid/man3/pthread_mutex_init.3.html#contenttoc4) –

8

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

мьютекс:

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

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

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

Семафор:

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

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

35

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

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

Разница между мьютексом и Binary-Семафор является принцип собственности:

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

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

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

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

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

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

Mutex vs. Semaphores – Part 1: Semaphores

Mutex vs. Semaphores – Part 2: The Mutex

Mutex vs. Semaphores – Part 3 (final part): Mutual Exclusion Problems

+0

URL-адреса этого сайта содержат фанки-персонажи и не работают поэтому ... Я над этим работаю –

+0

Исправлены символы юникода в урсах, теперь работают ссылки. –

67

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

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

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

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

+0

, чтобы добавить: семафоры и мьютексы - два способа обеспечить синхронизацию. семафор, могут быть более связаны с сигнализацией (например, сценарий проблем производителей и потребителей) и мьютексом, могут быть более связаны с возможностью доступа к одному за раз (несколько запросов на доступ к общему ресурсу, но только по одному предоставленному за раз). [хорошая статья: http://www.geeksforgeeks.org/mutex-vs-semaphore/] – parasrish

7

Попытка не озвучивать, но не может помочь себе.

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

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

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

наблюдение.1 Семафор содержит мьютексы

наблюдения.2 Мьютекс не семафор, а семафор не является мьютексом.

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

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

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

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

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

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

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

  1. один счетчик со значением 0 или 1 и сигнализации, когда значение переходит к 1, а затем отпирает один из парня ожидания на сигнале == Двоичный семафор

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

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

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

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

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

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

5

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

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

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

1

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

2

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

+0

Продажа билетов - это примерный пример. Пример семафора немного неясен (мне все равно). – prayagupd

+1

@prayagupd Семафор пример - это создавать потоки в некотором порядке, тогда как продавать билеты не нужно никакого заказа. Если есть три человека: a, b и c. Когда они приходят покупать билеты, нам все равно не нужно покупать билеты. Однако, если мы сделаем такой расчет: 'x = getx(); y = gety(); z = x + y; 'По какой-то причине мы используем три потока для выполнения трех вещей, теперь порядок потоков очень важен, потому что мы не можем делать' x + y', если 'getx' и' gety' не закончились , Одним словом, семафор используется, когда мы заботимся о порядке выполнения многопоточности. – Yves

+0

достал тебя. Это похоже на [барьер] (https://en.wikipedia.org/wiki/Barrier_ (computer_science)). Я могу сказать, что дождитесь завершения '' '' '' '' '' '' '' '' '' '' '' 'и затем вычислить' z = x + y'. Я знаю, что java имеет ['CyclicBarrier'] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CyclicBarrier.html). Кроме того, я не уверен, могу ли я сказать, что «mapreduce» также является семафором usecase, потому что я не могу «уменьшить» до тех пор, пока все «карты» не будут завершены. – prayagupd

0

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

Смежные вопросы