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

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

Они семантически одинаковы, но на практике вы заметите странные различия (особенно в Windows).
Michael Foukarakis 9.10.2009 05:30:17
@ Майкл Фукаракис: В чем странные различия?
Philipp 11.07.2010 13:56:54
Я полагаю, странное не правильное выражение. Мьютекс также поддерживает владение и иногда повторный вход. Это тот случай, в Windows. Кроме того, семафоры в Windows реализованы поверх объектов Event, однако я не уверен в практических последствиях этого.
Michael Foukarakis 11.07.2010 15:13:44
Подобное обсуждение в stackoverflow.com/questions/4039899/…
Karthik Balaguru 5.11.2014 08:09:08
@philipxy Отлично спрятал «rn» вместо «m».
Mooncrater 20.10.2018 11:09:41
30 ОТВЕТОВ
  • Мьютекс может быть освобожден только поток , который приобрел его .
  • Бинарный семафор может быть передан любым потоком (или процесса).

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

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

444
25.10.2019 21:53:00
Mutex can be released only by thread that had acquired it- Я только что попытался с помощью простой программы на основе pthread_mutex, поток может разблокировать мьютекс, заблокированный в основном потоке
daisy 28.07.2012 03:55:49
@ warl0ck Согласно man-странице pthread_mutex_lock linux.die.net/man/3/pthread_mutex_lock : "Если тип мьютекса - PTHREAD_MUTEX_ERRORCHECK, то должна быть обеспечена проверка ошибок .... Если поток пытается разблокировать мьютекс, который он имеет не заблокирован или мьютекс, который разблокирован, возвращается ошибка ".
amit 11.01.2013 10:20:40
@ warl0ck См. stackoverflow.com/a/5492499/385064 'Pthreads имеет 3 различных типа мьютексов: быстрый мьютекс, рекурсивный мьютекс и мьютекс проверки ошибок. Вы использовали быстрый мьютекс, который по соображениям производительности не будет проверять эту ошибку. Если вы используете мьютекс проверки ошибок в Linux, вы получите ожидаемые результаты ».
FrostNovaZzz 27.11.2013 06:37:10
В нашем коде мы использовали мьютекс также для целей синхронизации. Поток, который блокирует мьютекс, снова пытался заблокировать мьютекс. Затем он переходит в заблокированное состояние. Мы видели, что мы можем разблокировать его из другого потока. синхронизация между ними. Мы используем только стандарт posix. Так что основное различие между мьютексом и двоичным семафором кажется расплывчатым.
achoora 18.02.2016 08:37:33
@achoora Я согласен, что неправильно синхронизировать семафор. На самом деле все мьютекс, двоичный семафор, барьер, конвейеры - это разные шаблоны для синхронизации. С точки зрения дизайна мьютекс больше похож на шаблон состояния, где алгоритм, выбранный состоянием, может изменять состояние. Бинарный семафор больше похож на шаблон стратегии, где внешний алгоритм может изменить состояние и, в конечном итоге, алгоритм / стратегию, выбранные для запуска.
shuva 17.05.2016 18:39:51

Ответ может зависеть от целевой ОС. Например, по крайней мере одна из знакомых мне реализаций RTOS позволит выполнять несколько последовательных операций «get» для одного мьютекса ОС, при условии, что все они находятся в одном и том же контексте потока. Множественное получение должно быть заменено равным количеством операций, прежде чем другой поток сможет получить мьютекс. Это отличается от двоичных семафоров, для которых допускается только одно получение, независимо от контекста потока.

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

{
    mutexGet();  // Other threads can no longer get the mutex.

    // Make changes to the protected object.
    // ...

    objectModify();  // Also gets/puts the mutex.  Only allowed from this thread context.

    // Make more changes to the protected object.
    // ...

    mutexPut();  // Finally allows other threads to get the mutex.
}

Конечно, при использовании этой функции вы должны быть уверены, что все обращения в пределах одного потока действительно безопасны!

Я не уверен, насколько распространен этот подход или применяется ли он вне систем, с которыми я знаком. Пример такого мьютекса см. В RTOS ThreadX.

1
15.09.2008 13:55:00
Виды мьютекса, о которых вы говорите, называются «рекурсивным мьютексом», и их следует избегать, поскольку они медленные и способствуют плохому дизайну: (см. David Butenhof: zaval.org/resources/library/butenhof1.html )
gaspard 21.01.2010 09:20:00
Согласовано. В этой конкретной ОС я использую службу мьютекса, где хочу прояснить, что код предназначен для «взаимного исключения», а не для подсчета ссылок, но я не использую рекурсивную функцию из-за страха отвратительного раскручивания. Тем не менее, в контексте вопроса, это важное различие между «мьютексом» и «двоичным семафором».
Casey Barker 21.01.2010 13:53:19

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

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

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

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

  - SemTake
  - Критический раздел
  - SemGive

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

  Нить A Нить B
   Возьми Мутекс
     доступ к данным
     ... возьми мьютекс <== заблокируешь
     ...
   Предоставить Mutex доступ к данным <== Разблокирует
                                  ...
                                Дайте мьютекс

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

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

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

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

685
24.04.2013 00:07:59
Разве мьютекс не лучше бинарного семафора? Поскольку не имеет смысла, если кто-то снимает блокировку, которую он на самом деле не держит.
Pacerier 8.12.2011 16:31:15
У них разные цели. Mutex для эксклюзивного доступа к ресурсу. Для синхронизации следует использовать двоичный семафор (например, «Эй, кто-то! Это произошло!»). Двоичный «даритель» просто уведомляет любого «получателя» о том, что произошло.
Benoit 9.12.2011 17:16:58
@Pacerier Вы путаете цель. Мьютекс предназначен для защиты критической области. Вы правы, не имеет смысла использовать двоичный семафор. Я обновлю ответ, чтобы объяснить цель каждого.
Benoit 7.01.2012 17:48:43
@Benoit Итак, можем ли мы сказать, что Mutex используются для атомарности, а бинарный семафор для перспективы упорядочения, поскольку задача B будет ожидать, пока задача A сообщит о снятии блокировки, которая по своей природе будет обеспечивать порядок операций над структурой данных?
abhi 23.02.2014 09:16:11
@abhi Это хороший способ посмотреть на Mutex. Однако, в зависимости от операционной системы, на двоичном семафоре может ожидаться более одного получателя. В этом случае только один из клиентов получит двоичный sem. Другие будут ждать следующего. Порядок получения известен или гарантирован? Зависит от ОС.
Benoit 3.03.2014 16:01:33

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

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

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

42
27.09.2011 09:11:15

В Windows есть два различия между мьютексами и двоичными семафорами:

  1. Мьютекс может быть освобожден только тем потоком, который имеет право собственности, то есть потоком, который ранее вызывал функцию Wait (или который стал владельцем при создании). Семафор может быть освобожден любым потоком.

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

12
6.01.2009 11:07:04
Хороший ответ. В # 2 вы описываете рекурсивный мьютекс - не все мьютексы обязательно являются рекурсивными. Например, cs.wustl.edu/~schmidt/ACE.FAQ.html#Q14
Dan 28.02.2010 18:49:42

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

5
22.11.2008 18:24:59

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

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

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

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

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.

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

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

23
23.11.2008 13:11:12
Я не думаю, что обычной практикой является использование мьютекса с помощью спин-блокировки. На машине Uni-proc это было бы абсолютно ужасно для производительности.
Evan Teran 22.11.2008 20:11:27
Обычно вы используете спин-блокировки только на многопроцессорных системах.
ConcernedOfTunbridgeWells 23.11.2008 13:09:01
Даже на SMP, после нескольких вращений вы возвращаетесь к режиму сна / бодрствования с помощью ОС. (например, futexсуществует системный вызов Linux , чтобы помочь реализации мьютекса / семафора в пользовательском пространстве с низкой задержкой. en.wikipedia.org/wiki/Futex ) В быстром пути без конфликтов, или если ресурс скоро станет доступным, у вас никогда не будет лишних затрат системный вызов. Но вы не тратите больше нескольких микросекунд на ожидание (вращение). Конечно, настройка параметров отката и ожидания спин-цикла зависит от аппаратного обеспечения и рабочей нагрузки, но стандартная библиотека обычно имеет разумный выбор.
Peter Cordes 26.10.2019 04:01:03

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

мьютекс:

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

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

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

Семафор:

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

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

442
6.12.2008 19:53:46
... но это касается мьютекса против счетного семафора. Был задан вопрос о бинарном.
Roman Nikitchenko 10.11.2009 07:47:37
Хотя то, что сказал Дэвид, верно, но это НЕ ответ на заданный вопрос. Ответ Младена Янковича - это ответ на заданный вопрос, где указывается, что нужно различать «бинарный семафор» и «мьютекс».
Ajeet Ganga 21.08.2011 15:45:11
К сожалению, этот неправильный ответ имеет больше голосов, чем лучший ответ @Benoit
NeonGlow 29.04.2013 09:18:43
Этот ответ вводит в заблуждение. Его следует сравнивать только с двоичным семафором.
Hemanth 15.03.2014 08:27:07
Это также демонстрирует проблему с использованием счетного семафора для защиты общего ресурса: если ключи действительно идентичны, и туалет разблокирован с помощью ключа, и нет другого механизма для распределения использования ячейки, то: (1) первый пользователь разблокирует, входит и начинает использовать первую ячейку. (2) следующий пользователь открывает, входит и начинает использовать первую ячейку ...
Technophile 20.04.2015 04:46:38

Хорошие статьи на эту тему:

Из части 2:

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

150
28.06.2016 14:27:11
Спасибо за ссылку, объяснения там отличные. Ссылка изменилась: feabhas.com/blog/2009/09/… (Используйте <Пред и След> для перехода к двум другим статьям.
Aaron H. 13.05.2010 23:03:17
@ Аарон Я исправил ссылки
Judge Maygarden 2.06.2010 14:36:05
Примечание. Отсутствие прав собственности также не позволяет операционной системе работать вокруг инверсии приоритетов. По этой причине я обычно использую условные переменные, а не семафоры для архитектур производитель / потребитель.
kgriffs 4.02.2011 19:49:08
+1 за отличные ссылки на статьи. Лучшая статья, объясняющая семафор и мьютекс с помощью слов «что это такое» и «что это делает» computing.llnl.gov/tutorials/pthreads. Я использовал эту статью в качестве ссылки на сцену, которая технически все объясняет мьютекс / условные выражения и другие конструкции, построенные на их вершине, такие как семафор / барьер / читатель-писатель, но нигде явно и кратко о проблемах, с которыми сталкиваются конструкции. Короче это ссылка. :)
Ajeet Ganga 21.08.2011 16:15:37
легче понять, чем другие ответы.
BinaryTreeee 31.12.2018 06:15:25

Измененный вопрос - в чем разница между мьютексом и «двоичным» семафором в «Linux»?

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

II) Mutex легкий и быстрее, чем семафор. Futex еще быстрее

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

6
3.05.2010 09:36:51
я неправ. II) Источник? III) Это зависит.
curiousguy 24.10.2011 07:39:11

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

4
18.08.2010 22:10:00
В каких конкретных случаях гарантируется справедливость для семафоров, но не для мьютексов?
curiousguy 24.10.2011 07:34:22
POSIX имеет специфические требования, поток должен быть разбужен sem_post()для SCHED_FIFOи SCHED_RR(оба из них не по умолчанию): наивысший приоритет потока, и , если есть несколько с тем же приоритетом, нити , которые долго ждали дольше. OpenSolaris в некоторой степени следует этому правилу FIFO даже для обычного планирования. Для glibc и FreeBSD разблокировка простого мьютекса (т.е. не приоритетная защита или наследование приоритетов) и публикация семафора в основном одинаковы, помечая объект как разблокированный, а затем, если могут быть ожидающие потоки, вызывать ядро ​​для пробуждения одного из них.
jilles 26.10.2011 19:37:12

Мьютекса контролирует доступ к одному общему ресурсу. Он предоставляет операции для получения () доступа к этому ресурсу и освобождения () его по завершении.

Семафор управляет доступом к общему пулу ресурсов. Он предоставляет операции Wait () до тех пор, пока один из ресурсов в пуле не станет доступным, и Signal (), когда он возвращается в пул.

Когда количество ресурсов, которые защищает семафор, больше 1, оно называется счетным семафором . Когда он управляет одним ресурсом, он называется булевым семафором . Булев семафор эквивалентен мьютексу.

Таким образом, семафор - это абстракция более высокого уровня, чем Mutex. Mutex может быть реализован с использованием семафора, но не наоборот.

8
6.03.2011 17:53:42

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

4
23.02.2012 09:38:13

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

1
2.03.2012 11:03:39
Что такое владение? Вы имеете в виду, что контекст, который приобретает мьютекс, может только открыть его. ??
Raulp 30.05.2012 15:15:39

http://www.geeksforgeeks.org/archives/9102 обсуждает в деталях.

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

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

5
26.11.2012 06:43:17

Вы, очевидно, используете мьютекс для блокировки данных в одном потоке, к которым одновременно обращается другой поток. Предположим, что вы только что позвонили lock()и в процессе доступа к данным. Это означает, что вы не ожидаете, что какой-либо другой поток (или другой экземпляр того же кода потока) получит доступ к тем же данным, заблокированным тем же мьютексом. То есть, если один и тот же код потока выполняется в другом экземпляре потока, блокируется, тоlock()должен блокировать поток управления там. Это относится к потоку, который использует другой код потока, который также обращается к тем же данным и который также заблокирован тем же мьютексом. В этом случае вы все еще находитесь в процессе доступа к данным, и вам может потребоваться, скажем, еще 15 секунд, чтобы достичь разблокировки мьютекса (чтобы другой поток, блокируемый блокировкой мьютекса, разблокировался и позволил элементу управления доступ к данным). Разрешаете ли вы любой ценой позволить другому потоку просто разблокировать тот же мьютекс и, в свою очередь, разрешить потоку, который уже ожидает (блокирует) блокировку мьютекса, разблокировать и получить доступ к данным? Надеюсь, вы поняли, что я здесь говорю? Согласно согласованному универсальному определению!

  • с «мьютексом» этого не может быть. Никакая другая тема не может разблокировать блокировку в вашей теме.
  • с «двоичным семафором» это может произойти. Любая другая тема может разблокировать блокировку в вашей теме

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

10
11.12.2012 16:42:33

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

2
19.03.2013 08:09:06

Mutex используются для «Механизмов блокировки». один процесс за раз может использовать общий ресурс

в то время как

Семафоры используются для «Сигнальных механизмов», таких как «Я закончил, теперь могу продолжить»

10
17.05.2013 19:55:15

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

Когда мы пытаемся дать семафор, не беря его, он проходит. Но когда вы пытаетесь дать мьютекс, не беря его, это не получается. Я проверил это на платформе Windows. Включите USE_MUTEX для запуска того же кода, используя MUTEX.

#include <stdio.h>
#include <windows.h>
#define xUSE_MUTEX 1
#define MAX_SEM_COUNT 1

DWORD WINAPI Thread_no_1( LPVOID lpParam );
DWORD WINAPI Thread_no_2( LPVOID lpParam );

HANDLE Handle_Of_Thread_1 = 0;
HANDLE Handle_Of_Thread_2 = 0;
int Data_Of_Thread_1 = 1;
int Data_Of_Thread_2 = 2;
HANDLE ghMutex = NULL;
HANDLE ghSemaphore = NULL;


int main(void)
{

#ifdef USE_MUTEX
    ghMutex = CreateMutex( NULL, FALSE, NULL);
    if (ghMutex  == NULL) 
    {
        printf("CreateMutex error: %d\n", GetLastError());
        return 1;
    }
#else
    // Create a semaphore with initial and max counts of MAX_SEM_COUNT
    ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaphore error: %d\n", GetLastError());
        return 1;
    }
#endif
    // Create thread 1.
    Handle_Of_Thread_1 = CreateThread( NULL, 0,Thread_no_1, &Data_Of_Thread_1, 0, NULL);  
    if ( Handle_Of_Thread_1 == NULL)
    {
        printf("Create first thread problem \n");
        return 1;
    }

    /* sleep for 5 seconds **/
    Sleep(5 * 1000);

    /*Create thread 2 */
    Handle_Of_Thread_2 = CreateThread( NULL, 0,Thread_no_2, &Data_Of_Thread_2, 0, NULL);  
    if ( Handle_Of_Thread_2 == NULL)
    {
        printf("Create second thread problem \n");
        return 1;
    }

    // Sleep for 20 seconds
    Sleep(20 * 1000);

    printf("Out of the program \n");
    return 0;
}


int my_critical_section_code(HANDLE thread_handle)
{

#ifdef USE_MUTEX
    if(thread_handle == Handle_Of_Thread_1)
    {
        /* get the lock */
        WaitForSingleObject(ghMutex, INFINITE);
        printf("Thread 1 holding the mutex \n");
    }
#else
    /* get the semaphore */
    if(thread_handle == Handle_Of_Thread_1)
    {
        WaitForSingleObject(ghSemaphore, INFINITE);
        printf("Thread 1 holding semaphore \n");
    }
#endif

    if(thread_handle == Handle_Of_Thread_1)
    {
        /* sleep for 10 seconds */
        Sleep(10 * 1000);
#ifdef USE_MUTEX
        printf("Thread 1 about to release mutex \n");
#else
        printf("Thread 1 about to release semaphore \n");
#endif
    }
    else
    {
        /* sleep for 3 secconds */
        Sleep(3 * 1000);
    }

#ifdef USE_MUTEX
    /* release the lock*/
    if(!ReleaseMutex(ghMutex))
    {
        printf("Release Mutex error in thread %d: error # %d\n", (thread_handle == Handle_Of_Thread_1 ? 1:2),GetLastError());
    }
#else
    if (!ReleaseSemaphore(ghSemaphore,1,NULL) )      
    {
        printf("ReleaseSemaphore error in thread %d: error # %d\n",(thread_handle == Handle_Of_Thread_1 ? 1:2), GetLastError());
    }
#endif

    return 0;
}

DWORD WINAPI Thread_no_1( LPVOID lpParam ) 
{ 
    my_critical_section_code(Handle_Of_Thread_1);
    return 0;
}


DWORD WINAPI Thread_no_2( LPVOID lpParam ) 
{
    my_critical_section_code(Handle_Of_Thread_2);
    return 0;
}

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

4
6.07.2019 23:41:20
Если вы прочитаете другие ответы, станет ясно, что концепция «владения» имеет смысл только с мьютексами, а не с семафорами. Семафоры могут использоваться для таких вещей, как поток, сообщающий другим потокам, что обработка фрагмента данных завершена; результаты готовы к прочтению.
Peter Cordes 26.10.2019 04:06:37

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

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

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

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

99
29.11.2017 13:53:16

Миф:

Пара статей говорит, что «двоичный семафор и мьютекс одинаковы» или «семафор со значением 1 является мьютексом», но основное отличие в том, что Mutex может быть освобожден только тем потоком, который его получил, в то время как вы можете сигнализировать семафор из любого другого потока

Ключевые моменты:

• Поток может получить более одной блокировки (Mutex).

• Мьютекс может быть заблокирован более одного раза, только если это рекурсивный мьютекс, здесь блокировка и разблокировка для мьютекса должны быть одинаковыми

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

• Двоичный семафор и мьютекс похожи, но не одинаковы.

• Mutex является дорогостоящей операцией из-за протоколов защиты, связанных с ним.

• Основная цель мьютекса - добиться атомарного доступа или блокировки ресурса.

9
29.05.2014 23:54:45

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

19
24.08.2014 06:17:24
«может быть передано другим потоком», что это значит, приведите пример.
Myanju 17.08.2017 18:52:21

Разница между двоичным семафором и мьютексом: ВЛАДЕНИЕ: Семафоры могут сигнализироваться (публиковаться) даже от не текущего владельца. Это означает, что вы можете просто отправлять сообщения из любой другой ветки, хотя вы не являетесь владельцем.

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

6
30.03.2015 11:46:22

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

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

В случае с semaphone это не так. Семафор не связан с определенным идентификатором потока.

0
10.12.2018 04:09:49

Почти все вышесказанное говорит правильно. Позвольте мне также попытаться уточнить, есть ли у кого-то сомнения.

  • Mutex -> используется для сериализации
  • Семафор-> Синхронизация.

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

Стандартный пример-> проблема потребителя производителя.

initial value of SemaVar=0

Producer                           Consumer
---                                SemaWait()->decrement SemaVar   
produce data
---
SemaSignal SemaVar or SemaVar++  --->consumer unblocks as SemVar is 1 now.

Надеюсь, я смогу уточнить.

-2
26.10.2019 04:12:07
одинаковая функциональность может быть достигнута через них обоих . Мьютекс может проверить, что он разблокирован только тем же потоком, который его заблокировал, потому что все остальное является ошибкой для мьютекса . Если вы хотите подождать, пока другой поток не перенаправится stdout, или что-то в этом роде, нет очевидного способа реализовать это с помощью мьютекса. Собираетесь ли вы взять / снять блокировку вокруг каждого использования stdout? Это даже не работает, вы не знали бы, принял ли другой поток / освободил мьютекс.
Peter Cordes 26.10.2019 04:15:03
Если вы удалите это утверждение, пример может оказаться полезным.
Peter Cordes 26.10.2019 04:19:09

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

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

1
10.02.2016 02:12:46

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

  • Случайный выпуск
  • Рекурсивный тупик
  • Задача Смертельный тупик

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

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

pthread_mutex_t mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init (&mutex, &attr);

После инициализации мы можем поместить эти проверки в наш код следующим образом:

if(pthread_mutex_unlock(&mutex)==EPERM)
 printf("Unlock failed:Mutex not owned by this thread\n");
4
8.02.2017 09:51:21

Мьютекс: Предположим, что у нас есть критическая секция, которую 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, и это позволяет другой функции использовать критическую секцию. следовательно, в двоичном семафорном потоке нет владения.

15
3.12.2017 05:04:03

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

  1. То, как вы называете каждого из них.

  2. Максимальная длина «идентификатора».

-1
23.05.2019 04:48:29

Mutex

Мьютексы, как правило, используются для сериализации доступа к разделу повторно входящего кода, который не может быть выполнен одновременно более чем одним потоком. Объект мьютекса позволяет только одному потоку в управляемый раздел, заставляя другие потоки, которые пытаются получить доступ к этому разделу, ждать, пока первый поток не выйдет из этого раздела. Правильное использование мьютекса для защиты общего ресурса может быть опасным непреднамеренный побочный эффект. Любые две задачи ОСРВ, которые работают с разными приоритетами и координируются через мьютекс, создают возможность для инверсии приоритетов . Mutex работает в пространстве пользователя .

семафор

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

2
12.07.2019 07:18:50