Разница между двоичным семафором и мьютексом - PullRequest
744 голосов
/ 15 сентября 2008

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

Ответы [ 30 ]

640 голосов
/ 17 сентября 2008

Они НЕ одно и то же. Они используются для разных целей!
Хотя оба типа семафоров имеют полное / пустое состояние и используют один и тот же API, их использование сильно различается.

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

Семафор Mutex "принадлежит" задаче, которая его выполняет. Если Задача B попытается передать мьютекс, который в настоящее время находится в Задаче A, вызов Задачи B возвратит ошибку и завершится ошибкой.

Мьютексы всегда используют следующую последовательность:

  - SemTake
  - Critical Section
  - SemGive

Вот простой пример:

  Thread A                     Thread B
   Take Mutex
     access data
     ...                        Take Mutex  <== Will block
     ...
   Give Mutex                     access data  <== Unblocks
                                  ...
                                Give Mutex

Бинарный семафор
Бинарный семафор решает совершенно другой вопрос:

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

   Task A                      Task B
   ...                         Take BinSemaphore   <== wait for something
   Do Something Noteworthy
   Give BinSemaphore           do something    <== unblocks

Обратите внимание, что для двоичного семафора нормально, если B берет семафор, а A - его.
Опять же, двоичный семафор НЕ защищает ресурс от доступа. Акт «Давать и брать семафор» в корне не связан.
Как правило, для одной и той же задачи не имеет смысла давать один и тот же двоичный семафор.

419 голосов
/ 06 декабря 2008

Пример туалета - приятная аналогия:

Мьютекс:

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

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

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

Семафор:

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

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

413 голосов
/ 15 сентября 2008

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

В Windows двоичные семафоры больше похожи на объекты событий, чем на мьютексы.

140 голосов
/ 09 октября 2009

Приятных статей по теме:

Из части 2:

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

93 голосов
/ 21 ноября 2013

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

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

Семафор - это сигнальный механизм (сигнал типа «Я готов, вы можете продолжить»). Например, если вы слушаете песни (примите это как одно задание) на вашем мобильном телефоне, и в то же время ваш друг позвонил вам, будет запущено прерывание, при котором подпрограмма обработки прерывания (ISR) подаст сигнал для обработки вызова на пробуждение.

Источник: http://www.geeksforgeeks.org/mutex-vs-semaphore/

37 голосов
/ 24 сентября 2008

Их семантика синхронизации очень различна:

  • мьютексы позволяют сериализовать доступ к данному ресурсу, т. Е. Несколько потоков ожидают блокировку, по одному за раз, и, как было сказано ранее, поток владеет блокировкой, пока она не будет выполнена: только этот конкретный поток может разблокировать его.
  • двоичный семафор - это счетчик со значениями 0 и 1: задача блокируется до тех пор, пока любая задача не выполнит sem_post. Семафор объявляет, что ресурс доступен, и предоставляет механизм для ожидания, пока он не сообщит о доступности.

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

35 голосов
/ 20 июня 2013
  • A Mutex , по определению, используется для сериализации доступа к разделу повторяющегося кода, который не может быть выполнен более одной нити.

  • A Семафор , по определению, ограничивает количество одновременных пользователей общего ресурса до максимальное количество

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

  • И семафоры, и Mutex (по крайней мере, в последнем ядре) по своей природе нерекурсивны.
  • Никто не владеет семафорами, тогда как Mutex является собственностью, и владелец несет ответственность за них. Это важный различие с точки зрения отладки.
  • В случае Mutex, поток, которому принадлежит Mutex, отвечает за его освобождение. Однако в случае семафоров это условие не требуется. Любой другой поток может подать сигнал на освобождение семафора с помощью s m p s (function.e_ot)

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

  • Природа семафоров позволяет использовать их при синхронизации связанных и несвязанных процессов, а также между потоки. Mutex может использоваться только для синхронизации между потоками и, самое большее, между связанными процессами (pthread Реализация последнего ядра поставляется с функцией, которая позволяет использовать Mutex между связанными процессами).
  • Согласно документации ядра, Mutex легче по сравнению с семафорами. Это означает, что программа при использовании семафора занимает больше места в памяти по сравнению с программой, имеющей Mutex.
  • С точки зрения использования, Mutex имеет более простую семантику по сравнению с семафорами.
21 голосов
/ 22 ноября 2008

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

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

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

Типичная реализация мьютекса имеет процесс или поток, выполняющий инструкцию test-and-set и оценивающий, установил ли мьютекс что-либо еще. Ключевым моментом здесь является отсутствие взаимодействия с планировщиком , поэтому мы понятия не имеем (и нам все равно), кто установил блокировку. Затем мы либо оставляем наш временной интервал и повторяем попытку при повторном планировании задачи, либо выполняем spin-lock . Спин-блокировка - это алгоритм вроде:

Count down from 5000:
     i. Execute the test-and-set instruction
    ii. If the mutex is clear, we have acquired it in the previous instruction 
        so we can exit the loop
   iii. When we get to zero, give up our time slice.

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

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

Основной алгоритм семафора выглядит так:

(somewhere in the program startup)
Initialise the semaphore to its start-up value.

Acquiring a semaphore
   i. (synchronised) Attempt to decrement the semaphore value
  ii. If the value would be less than zero, put the task on the tail of the list of tasks waiting on the semaphore and give up the time slice.

Posting a semaphore
   i. (synchronised) Increment the semaphore value
  ii. If the value is greater or equal to the amount requested in the post at the front of the queue, take that task off the queue and make it runnable.  
 iii. Repeat (ii) for all tasks until the posted value is exhausted or there are no more tasks waiting.

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

РЕДАКТИРОВАТЬ: Как справедливо заметил Эван, спин-блокировки будут замедлять однопроцессорную машину. Вы должны использовать спин-блокировку только на многопроцессорном блоке, потому что на одном процессоре процесс, удерживающий мьютекс, никогда не сбросит его, пока выполняется другая задача. Спин-блокировки полезны только на многопроцессорных архитектурах.

18 голосов
/ 24 августа 2014

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

11 голосов
/ 06 августа 2017

Mutex: Предположим, у нас есть критическая секция, которую T1 хочет получить к ней доступ, затем она выполняет следующие шаги T1:

  1. Замок
  2. Использовать критический раздел
  3. Разблокировка

Двоичный семафор: работает на основе сигнала ожидания и сигнала. wait (s) уменьшить значение "s" на единицу, обычно значение "s" инициализируется значением "1", Сигнал (ы) увеличивает значение "s" на единицу. если значение "s" равно 1, значит, никто не использует критическую секцию, когда значение равно 0, означает, что критическая секция используется. Предположим, что поток T2 использует критическую секцию, а затем следует следующие шаги. T2:

  1. wait (s) // изначально значение s равно единице после вызова wait, его значение уменьшилось на единицу, т.е. 0
  2. Использовать критическую секцию
  3. signal (s) // теперь значение s увеличивается и становится 1

Основное различие между Mutex и двоичным семафором заключается в Mutext, если поток блокирует критическую секцию, тогда он должен разблокировать критическую секцию, никакой другой поток не может разблокировать его, но в случае двоичного семафора, если один поток блокирует критическую секцию, используя wait (s) функция тогда значение s становится "0", и никто не может получить к нему доступ, пока значение "s" не станет 1, но предположим, что какой-то другой поток вызывает сигнал (и), тогда значение "s" станет 1, и это позволяет другой функции использовать критическую секцию , следовательно, в двоичном семафорном потоке нет владения.

...