- •Типы блокировок (механизмов синхронизации)
- •Определение семафора
- •Применение семафоров
- •Проблемы семафоров
- •Мьютексы в Win32 api
- •Мьютексы в Unix-подобных системах
- •Мьютексы в языке Си
- •Простейший пример взаимной блокировки
- •Специфика многопроцессорных и однопроцессорных конфигураций
- •Применение спинлоков
- •Проблемы спинлоков и методы их решения
- •Альтернативы спинлоков
- •Прочие модификации спинлоков
Применение семафоров
Вот некоторые из проблем, которые могут решать семафоры.
запрет одновременного выполнения заданных участков кода;
поочерёдный доступ к критическому ресурсу (важному ресурсу, для которого невозможен (или нежелателен) одновременный доступ).
Проблемы семафоров
Во-первых, можно написать программу с «утечкой семафора», вызвав enter() и забыв вызвать leave(). Реже встречаются ошибки, когда дважды вызывается leave().
Во-вторых, семафоры чреваты взаимной блокировкой потоков.
В-третьих, остаётся проблема синхронизации процедур самого семафора. Например, возможна следующая ситуация: два процесса ждут освобождения семафора. После того, как семафор освободился, первый процесс «узнаёт» об этом, но не успевает увеличить счётчик, как управление передаётся второму процессу. Второй процесс тоже узнаёт об освобождении семафора, увеличивает счётчик и входит в защищённый участок кода. Тут управление передаётся первому процессу, тот ещё раз увеличивает счётчик и тоже входит в защищённый участок кода. В итоге имеем превышение разрешённого числа процессов.
Данная проблема не имеет алгоритмического решения. Она разрешается либо размещением процедуры ожидания в критической секции, в которой не разрешается переключение с процесса на процесс, либо программистскими приёмами наподобие осуществления проверки флага и его увеличения с помощью одной машинной команды.
Мью́текс (mutex, от mutual exclusion — «взаимное исключение») — аналог одноместного семафора, служащий в программировании для синхронизации одновременно выполняющихся потоков.
Мьютекс отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние.
Мьютексы — это один из вариантов семафорных механизмов для организации взаимного исключения. Они реализованы во многих ОС, их основное назначение — организация взаимного исключения для потоков из одного и того же или из разных процессов.
Мьютексы — это простейшие двоичные семафоры, которые могут находиться в одном из двух состояний — отмеченном или неотмеченном (открыт и закрыт соответственно). Когда какой-либо поток, принадлежащий любому процессу, становится владельцем объекта mutex, последний переводится в неотмеченное состояние. Если задача освобождает мьютекс, его состояние становится отмеченным.
Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом. В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом. Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток засыпает до тех пор, пока мьютекс не будет освобождён.
Цель использования мьютексов — защита данных от повреждения в результате асинхронных изменений (состояние гонки), однако могут порождаться другие проблемы — такие, как взаимная блокировка (клинч).
Мьютекс — одна из реализаций спинлока.
Мьютексы в Win32 api
Win32 API в Windows имеет две реализации мьютексов — собственно мьютексы, имеющие имена и доступные для использования между разными процессами, и критические секции, которые могут использоваться только в пределах одного процесса. Для каждого из этих двух типов мьютексов используются свои функции захвата и освобождения.
Критическая секция в Windows по возможности блокируется без использования вызова режима ядра (аналогично спинлоку), но при невозможности такой блокировки поток запрашивает ядро.
