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

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

<p>они <strong>не</strong> это одно и то же. они используются для разных целей!<br> хотя оба типа семафоров имеют полное/пустое состояние и используют один и тот же api, их использование сильно различается.</p><p><strong>семафоры взаимного исключения</strong><br> семафоры взаимного исключения используются для защиты общих ресурсов (структура данных, файл и т.д.).</p><p>семафор mutex "принадлежит" задаче, которая его выполняет. если задача b попытается передать мьютекс, который в данный момент находится в задаче a, вызов задачи b вернет ошибку и произойдет сбой.</p><p>мьютексы всегда используют следующую последовательность:</p><pre> - semtake - критический раздел - semgive</pre><p>вот простой пример:</p><pre> нить a нить b take mutex доступ к данным ... take mutex <== будет блокировать ... предоставить данные доступа mutex <== разблокирует ... предоставить mutex </pre><p><strong>двоичный семафор</strong><br> двоичный семафор решает совершенно другой вопрос:</p><ul> <li>задача b находится в ожидании, когда что-то произойдет (например, срабатывает датчик).</li> <li>срабатывает датчик и запускается программа обслуживания прерываний. нужно уведомить задачу о поездке.</li> <li>задача b должна быть выполнена и предпринять соответствующие действия для отключения датчика. затем вернитесь к ожиданию.</li> </ul><pre><code> task a task b ... take binsemaphore <== wait for something do something noteworthy give binsemaphore do something <== unblocks </code></pre><p>обратите внимание, что с двоичным семафором b может взять семафор и a дать его.<br> опять же, двоичный семафор не защищает ресурс от доступа. акт "давать и брать семафор" в корне не связан.<br> как правило, для одной и той же задачи мало смысла давать один и тот же двоичный семафор.</p>

<p> <a href="http://koti.mbnet.fi/niclasw/mutexsemaphore.html">пример туалета</a> - приятная аналогия:</p><blockquote> <p>мьютекс:</p> <p>это ключ к туалету. один человек может иметь ключ - занять туалет - в самый раз. когда закончено, человек дает (освобождает) ключ следующему человеку в очереди.</p> <p>официально: "мьютексы обычно используются для сериализации доступа к разделу повторно поступающего кода, который не может быть выполнен одновременно более чем одним потоком. объект мьютекса допускает только один поток в контролируемый раздел, заставляя другие потоки, которые пытаются получить доступ к этот раздел, чтобы дождаться выхода первого потока из этого раздела. " ссылка: библиотека разработчика symbian</p> <p>(мьютекс - это действительно семафор со значением 1.)</p> <p>семафор:</p> <p>количество бесплатных идентичных ключей от туалета. например, у нас есть четыре туалета с одинаковыми замками и ключами. счетчик семафоров - количество ключей - вначале устанавливается равным 4 (все четыре туалета свободны), тогда значение счетчика уменьшается по мере прихода людей. если все туалеты заполнены, т.е. свободных ключей не осталось, число семафоров равно 0. теперь, когда уравнение один человек выходит из туалета, семафор увеличивается до 1 (один свободный ключ) и передается следующему человеку в очереди.</p> <p>официально: "семафор ограничивает число одновременных пользователей общего ресурса до максимального числа. потоки могут запрашивать доступ к ресурсу (уменьшая семафор), и могут сигнализировать, что они закончили использовать ресурс (увеличивая семафор). " ссылка: библиотека разработчика symbian</p> </blockquote>

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

<p>хорошие статьи на эту тему:</p><ul> <li> <a href="https://blog.feabhas.com/2009/09/mutex-vs-semaphores-%e2%80%93-part-1-semaphores/">mutex vs. semaphores - часть 1: semaphores</a> </li> <li> <a href="https://blog.feabhas.com/2009/09/mutex-vs-semaphores-%e2%80%93-part-2-the-mutex/">mutex vs. semaphores - часть 2: mutex</a> </li> <li> <a href="https://blog.feabhas.com/2009/10/mutex-vs-semaphores-%e2%80%93-part-3-final-part-mutual-exclusion-problems/">mutex vs. semaphores - часть 3 (заключительная часть): проблемы взаимного исключения</a> </li> </ul><p><strong> из части 2: </strong></p><blockquote> <p>мьютекс похож на принципы двоичного семафора с одним существенным отличием: принцип владения. владение - это простая концепция, что когда задача блокирует (приобретает) мьютекс, только она может разблокировать (освободить) его. если задача пытается разблокировать мьютекс, который она не заблокировала (то есть не владеет), возникает условие ошибки, и, самое главное, мьютекс не разблокируется. если объект взаимного исключения не принадлежит, то, независимо от того, как он называется, он не является мьютексом.</p> </blockquote>

<p>поскольку ни один из приведенных выше ответов не устраняет путаницу, вот тот, который устраняет мою путаницу.</p><blockquote> <p>строго говоря, <strong> мьютекс - это механизм блокировки </strong>, используемый для синхронизации доступа к ресурсу. только одна задача (может быть потоком или процессом, основанным на абстракции ос) может получить мьютекс. это означает, что с мьютексом будет владение, и только владелец может снять блокировку (мьютекс).</p> <p><strong> семафор является сигнальным механизмом </strong> (вид сигнала "я готов, вы можете продолжить"). например, если вы слушаете песни (считаете, что это одно задание) на своем мобильном телефоне, и в то же время ваш друг звонил вам, будет запущено прерывание, при котором подпрограмма обработки прерывания (isr) будет сигнализировать о пробуждении задачи обработки вызова. ,.</p> </blockquote><p>источник: <a href="http://www.geeksforgeeks.org/mutex-vs-semaphore/">http://www.geeksforgeeks.org/mutex-vs-semaphore/</a> </p>

<p>их семантика синхронизации очень различна:</p><ul> <li>мьютексы позволяют сериализовать доступ к данному ресурсу, то есть несколько потоков ожидают блокировки по одному, и, как было сказано ранее, поток <em> владеет </em> блокировкой до это сделано: <strong>только</strong> этот конкретный поток может разблокировать его.</li> <li>двоичный семафор - это счетчик со значениями 0 и 1: задача блокируется до тех пор, пока <strong>любая</strong> задача не выполнит sem\_post. семафор объявляет, что ресурс доступен, и предоставляет механизм для ожидания, пока он не станет доступным.</li> </ul><p>таким образом, можно видеть мьютекс как токен, передаваемый от задачи к задачам, а семафор - как красный светофор (он <strong>сигнализирует</strong> кому-то, что он может продолжить).</p>

<ul> <li> <p>a <strong>mutex</strong> по определению используется для сериализации доступа к разделу повторно входящего кода, который не может быть выполнен одновременно более чем одним потоком.</p> </li> <li> <p>a <strong>семафор</strong> по определению ограничивает количество одновременных пользователей общего ресурса до максимального числа</p> </li> <li> <p>семафор может быть mutex, но mutex никогда не может быть семафором. это просто означает, что двоичный семафор может использоваться как mutex, но mutex никогда не может демонстрировать функциональность семафора.</p> </li> <li>и семафоры, и mutex (по крайней мере, в последних версиях ядра) нерекурсивны по своей природе.</li> <li>никто не владеет семафорами, в то время как mutex являются собственностью, и владелец несет ответственность за них. это важное отличие от точки зрения отладки.</li> <li> <p>в случае mutex, поток, которому принадлежит mutex, ответственен за его освобождение. однако в случае семафоров это условие не требуется. любой другой поток может подать сигнал на освобождение семафора, используя s m p s (function.e\_ot)</p> </li> <li> <p>другое различие, которое имело бы значение для разработчиков, состоит в том, что семафоры являются системными и остаются в форме файлов в файловой системе, если не очищены иным образом. mutex распространяется на весь процесс и автоматически очищается при выходе из процесса.</p> </li> <li>природа семафоров позволяет использовать их при синхронизации связанных и несвязанных процессов, а также между потоками. mutex может использоваться только для синхронизации между потоками и, самое большее, между связанными процессами (реализация pthread последнего ядра поставляется с функцией, позволяющей использовать mutex между связанными процессами).</li> <li>согласно документации ядра, mutex легче по сравнению с семафорами. это означает, что программа с использованием семафора имеет больший объем памяти по сравнению с программой, имеющей mutex.</li> <li>с точки зрения использования, mutex имеет более простую семантику по сравнению с семафорами.</li> </ul>

<p>на теоретическом уровне они не отличаются семантически. вы можете реализовать мьютекс, используя семафоры или наоборот (см. <a href="http://www.picturel.com/ucr/node32.html">здесь</a> для примера). на практике реализация отличается, и они предлагают немного разные услуги.</p><p>практическое отличие (с точки зрения окружающих их системных служб) состоит в том, что реализация мьютекса направлена на то, чтобы стать более легким механизмом синхронизации. в oracle-говорящих мьютексы известны как <a href="http://dbataj.blogspot.com/2007/10/oracle-latch.html">защелки</a> , а семафоры известны как <a href="http://www.dba-oracle.com/art\_dbazine\_waits.htm">ждет</a> .</p><p>на самом низком уровне они используют какой-то атомарный механизм <a href="http://en.wikipedia.org/wiki/test-and-set">test and set</a> . это считывает текущее значение ячейки памяти, вычисляет некоторый тип условия и записывает значение в этом месте в одной инструкции, которая <a href="http://en.wikipedia.org/wiki/atomic\_operation">не может быть прервана</a> . это означает, что вы можете приобрести мьютекс и проверить, есть ли у кого-то еще до вас.</p><p>типичная реализация мьютекса имеет процесс или поток, выполняющий инструкцию test-and-set и оценивающий, установил ли мьютекс что-либо еще. ключевым моментом здесь является то, что нет взаимодействия с <a href="http://en.wikipedia.org/wiki/scheduling\_(computing)">планировщик</a> , поэтому мы понятия не имеем (и нам все равно), кто установил блокировку. затем мы либо оставляем наш временной интервал и повторяем попытку при перепланировании задачи, либо выполняем <a href="http://en.wikipedia.org/wiki/spinlock">spin-lock</a> . спин-блокировка - это алгоритм вроде:</p><pre><code>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. </code></pre><p>когда мы закончим выполнение нашего защищенного кода (известного как <a href="http://en.wikipedia.org/wiki/critical\_section">критическая секция</a> ), мы просто устанавливаем значение мьютекса на ноль или любое другое значение, означающее "очистить". если несколько задач пытаются получить мьютекс, то следующая задача, запланированная после освобождения мьютекса, получит доступ к ресурсу. обычно вы используете мьютексы для управления синхронизированным ресурсом, где эксклюзивный доступ необходим только в течение очень коротких периодов времени, обычно для обновления общей структуры данных.</p><p>семафор - это синхронизированная структура данных (обычно с использованием мьютекса), которая имеет счетчик и некоторые оболочки системных вызовов, которые взаимодействуют с планировщиком немного глубже, чем библиотеки мьютекса. семафоры увеличиваются и уменьшаются и используются для <a href="http://en.wikipedia.org/wiki/blocking\_(scheduling)">блокировки</a> задач, пока что-то еще не будет готово. см. <a href="http://en.wikipedia.org/wiki/producer-consumer\_problem">проблема производителя/потребителя</a> для простого примера этого. семафоры инициализируются до некоторого значения - двоичный семафор - это просто особый случай, когда семафор инициализируется равным 1. публикация на семафор приводит к пробуждению процесса ожидания.</p><p>основной алгоритм семафора выглядит так:</p><pre><code>(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. </code></pre><p>в случае двоичного семафора основное практическое различие между ними заключается в характере системных служб, окружающих фактическую структуру данных.</p><p>правка: как справедливо указал эван, спин-блокировки будут замедлять однопроцессорный компьютер. вы должны использовать спин-блокировку только на многопроцессорном блоке, потому что на одном процессоре процесс, удерживающий мьютекс, никогда не сбросит его, пока выполняется другая задача. спин-блокировки полезны только на многопроцессорных архитектурах.</p>

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

<p>мьютекс: предположим, что у нас есть критическая секция, которую t1 хочет получить к ней доступ, затем она следует нижеуказанным шагам. t1:</p><ol> <li>замок</li> <li>используйте критический раздел</li> <li>отпереть</li> </ol><p>двоичный семафор: работает на основе сигнала ожидания и сигнала. wait (s) уменьшает значение "s" на единицу, обычно значение "s" инициализируется значением "1", сигнал (ы) увеличивает значение "s" на единицу. если значение "s" равно 1, значит, никто не использует критическую секцию, когда значение равно 0, означает, что критическая секция используется. предположим, что поток t2 использует критическую секцию, а затем следует следующие шаги. t2:</p><ol> <li>wait (s) // изначально значение s равно единице после вызова wait, его значение уменьшилось на единицу, т.е. 0</li> <li>использовать критический раздел</li> <li>signal (s) // теперь значение s увеличивается и становится 1</li> </ol><p>основное различие между mutex и двоичным семафором заключается в mutext, если поток блокирует критическую секцию, тогда он должен разблокировать критическую секцию, никакой другой поток не может разблокировать его, но в случае двоичного семафора, если один поток блокирует критическую секцию, используя функцию wait (s), тогда значение из s становится "0", и никто не может получить к нему доступ, пока значение "s" не станет 1, но предположим, что какой-то другой поток вызывает сигнал (ы), а затем значение "s" становится 1, и это позволяет другой функции использовать критическую секцию. следовательно, в двоичном семафорном потоке нет владения.</p>

<p>вы, очевидно, используете мьютекс для блокировки данных в одном потоке, к которым одновременно обращается другой поток. предположим, что вы только что вызвали <code>lock()</code> и находились в процессе доступа к данным. это означает, что вы не ожидаете, что какой-либо другой поток (или другой экземпляр того же кода потока) получит доступ к тем же данным, заблокированным тем же мьютексом. то есть, если один и тот же код потока исполняется в другом экземпляре потока, попадает в блокировку, тогда <code>lock()</code> должна блокировать поток управления там. это относится к потоку, который использует другой код потока, который также обращается к тем же данным и который также заблокирован тем же мьютексом. в этом случае вы все еще находитесь в процессе доступа к данным, и вам может потребоваться, скажем, еще 15 секунд, чтобы достичь разблокировки мьютекса (чтобы другой поток, блокируемый в блокировке мьютекса, разблокировался и позволил элементу управления доступ к данным). разрешаете ли вы любой ценой позволить еще одному потоку просто разблокировать тот же мьютекс и, в свою очередь, разрешить потоку, который уже ожидает (блокирует) блокировку мьютекса, разблокировать и получить доступ к данным? надеюсь, вы поняли, что я здесь говорю? согласно согласованному универсальному определению!</p><ul> <li>с "мьютексом" этого не может быть. никакая другая тема не может разблокировать блокировку в вашей теме.</li> <li>с "двоичным семафором" это может произойти. любая другая тема может разблокировать блокировку в вашей теме</li> </ul><p>итак, если вы очень осторожны в использовании бинарного семафора вместо мьютекса, тогда вам следует быть очень осторожным в "определении" блокировок и разблокировок. я имею в виду, что каждый поток управления, который затрагивает каждую блокировку, должен вызывать вызов разблокировки, также не должно быть никакой "первой разблокировки", скорее это должна быть всегда "первая блокировка".</p>

<p>mutex используются для "механизмов блокировки". один процесс за раз может использовать общий ресурс</p><p>в то время как</p><p>семафоры используются для "сигнальных механизмов", таких как "я закончил, теперь могу продолжить"</p>

<p>в windows есть два различия между мьютексами и двоичными семафорами:</p><ol> <li> <p>мьютекс может быть освобожден только тем потоком, который владеет, т. е. потоком, который ранее вызывал функцию wait (или который стал владельцем при создании). семафор может быть освобожден любым потоком.</p> </li> <li> <p>поток может повторно вызывать функцию ожидания в мьютексе без блокировки. однако, если вы дважды вызываете функцию ожидания для двоичного семафора без освобождения промежуточного семафора, поток блокируется.</p> </li> </ol>

<p>миф:</p><p>пара статей говорит, что "двоичный семафор и мьютекс одинаковы" или "семафор со значением 1 является мьютексом", но основное отличие в том, что mutex может быть освобожден только тем потоком, который его получил, в то время как вы можете сигнализировать семафор из любого другого потока</p><p>ключевые моменты:</p><p>• поток может получить более одной блокировки (mutex).</p><p>• мьютекс может быть заблокирован более одного раза, только если это рекурсивный мьютекс, здесь блокировка и разблокировка для мьютекса должны быть одинаковыми</p><p>• если поток, который уже заблокировал мьютекс, попытается снова заблокировать мьютекс, он войдет в список ожидания этого мьютекса, что приведет к взаимоблокировке.</p><p>• двоичный семафор и мьютекс похожи, но не одинаковы.</p><p>• mutex является дорогостоящей операцией из-за протоколов защиты, связанных с ним.</p><p>• основная цель мьютекса - добиться атомарного доступа или блокировки ресурса.</p>

<p>a <em>mutex</em> контролирует доступ к одному общему ресурсу. он предоставляет операции для <em>acqu ()</em> доступа к этому ресурсу и <em>release ()</em> когда это будет сделано.</p><p>a <em>семафор</em> контролирует доступ к общему пулу ресурсов. он предоставляет операции для <em>wait ()</em> до тех пор, пока один из ресурсов в пуле не станет доступным, и <em>signal ()</em>, когда он будет возвращен в пул.</p><p>когда количество ресурсов, которые защищает семафор, больше 1, оно называется <em>подсчет семафора</em>. когда он управляет одним ресурсом, он называется <em>логический семафор</em>. булев семафор эквивалентен мьютексу.</p><p>таким образом, семафор - это абстракция более высокого уровня, чем mutex. mutex может быть реализован с использованием семафора, но не наоборот.</p>

<p>измененный вопрос - в чем разница между мьютексом и "двоичным" семафором в "linux"?</p><p>ответ: ниже приведены различия: i) область действия. область действия мьютекса находится в адресном пространстве процесса, которое его создало, и используется для синхронизации потоков. принимая во внимание, что семафор может использоваться в пространстве процессов и, следовательно, он может использоваться для межпроцессной синхронизации.</p><p>ii) mutex является легким и быстрее, чем семафор. futex еще быстрее.</p><p>iii) mutex может быть успешно получен одним и тем же потоком несколько раз при условии, что он должен освобождать его одинаковое количество раз. другой поток, пытающийся получить, заблокирует. принимая во внимание, что в случае семафора, если тот же процесс пытается получить его снова, он блокируется, поскольку его можно получить только один раз.</p>

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

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

<p> <a href="http://www.geeksforgeeks.org/archives/9102">http://www.geeksforgeeks.org/archives/9102</a> подробно обсуждается.</p><p><code>mutex</code> - механизм блокировки, используемый для синхронизации доступа к ресурсу. <code>semaphore</code> - это механизм сигнализации.</p><p>это до программиста, если он/она хочет использовать двоичный семафор вместо мьютекса.</p>

<p>в окнах разница, как показано ниже. <strong>mutex:</strong> процесс, который успешно выполняется <strong>ожидание</strong> должен выполнить <strong>сигнал</strong> и наоборот. <strong>binary semaphores:</strong> различные процессы могут выполнять <strong>wait</strong> или <strong>signal</strong> операцию с семафором.</p>

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

<p>концепция была понятна мне после перехода над постами. но были некоторые затяжные вопросы. итак, я написал этот маленький кусочек кода.</p><p>когда мы пытаемся дать семафор, не беря его, он проходит. но когда вы пытаетесь дать мьютекс, не беря его, это не получается. я проверил это на платформе windows. разрешите use\_mutex для запуска того же кода, используя mutex.</p><pre><code>#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; } </code></pre>

<p>в то время как двоичный семафор может использоваться как мьютекс, мьютекс является более конкретным вариантом использования, так как только процесс, который заблокировал мьютекс, должен его разблокировать. это ограничение собственности позволяет обеспечить защиту от:</p><ul> <li>случайный выпуск</li> <li>рекурсивный тупик</li> <li>задача смертельный тупик</li> </ul><p>эти ограничения не всегда присутствуют, потому что они ухудшают скорость. во время разработки вашего кода вы можете временно включить эти проверки.</p><p>например вы можете включить атрибут проверки ошибок в своем мьютексе. ошибка проверки мьютексов возвращает <code>edeadlk</code>, если вы пытаетесь заблокировать один и тот же один дважды, и <code>eperm</code>, если вы разблокируете мьютекс, который не принадлежит вам.</p><pre><code>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); </code></pre><p>после инициализации мы можем поместить эти проверки в наш код следующим образом:</p><pre><code>if(pthread\_mutex\_unlock(&mutex)==eperm) printf("unlock failed:mutex not owned by this thread\n"); </code></pre>

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

<p>мьютексы имеют право собственности, в отличие от семафоров. хотя любой поток в рамках мьютекса может получить разблокированный мьютекс и заблокировать доступ к тому же критическому разделу кода, <em> только поток, который заблокировал мьютекс <strong>должен</strong> = разблокировать его </em>.</p>

<p>мьютекс и бинарный семафор используются одинаково, но в действительности они различны.</p><p>в случае мьютекса, разблокировать его может только заблокированный поток. если какой-то другой поток придет, чтобы заблокировать его, он будет ждать.</p><p>в случае с semaphone это не так. семафор не связан с конкретным идентификатором потока.</p>

<p>ответ может зависеть от целевой ос. например, по крайней мере одна rtos реализация, с которой я знаком, позволит несколько последовательных операций "get" для одного мьютекса ос, если они все находятся в одном и том же контексте потока. множественное получение должно быть заменено равным количеством операций, прежде чем другому потоку будет разрешено получить мьютекс. <em>это отличается от двоичных семафоров, для которых допускается только одно получение, независимо от контекста потока.</em></p><p>идея такого мьютекса заключается в том, что вы защищаете объект, позволяя изменять данные только в одном контексте. даже если поток получает мьютекс и затем вызывает функцию, которая дополнительно изменяет объект (и получает/помещает мьютекс защитника вокруг своих собственных операций), операции все равно должны быть безопасными, поскольку все они происходят в одном потоке.</p><pre><code>{ 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. } </code></pre><p>конечно, при использовании этой функции вы должны быть уверены, что все обращения в пределах одного потока действительно безопасны!</p><p>я не уверен, насколько распространен этот подход или применяется ли он вне систем, с которыми я знаком. пример такого мьютекса см. в rtos threadx.</p>

<p>как уже упоминали многие, мьютекс используется для защиты критического фрагмента кода (критический раздел aka). вы получите мьютекс (блокировку), войдите в критический раздел и освободите мьютекс (разблокировку) <strong>все в та же тема</strong>.</p><p>при использовании семафора вы можете заставить поток ждать семафор (скажем, поток a), пока другой поток (скажем, поток b) не завершит какую-либо задачу, а затем установить семафор для потока a, чтобы остановить ожидание и продолжить свою задачу.</p>

<p>"бинарный семафор" - это обход языка программирования, использующий "семафор", такой как "мьютекс". видимо, есть две очень большие различия:</p><ol> <li> <p>то, как вы называете каждого из них.</p> </li> <li> <p>максимальная длина "идентификатора".</p> </li> </ol>