Я слышал эти слова, связанные с параллельным программированием, но в чем разница между ними?
concurrency
locking
mutex
semaphore
Виктор
источник
источник
Ответы:
Блокировка позволяет только одному потоку войти в заблокированную часть, и блокировка не используется другими процессами.
Мьютекс - это то же самое, что и блокировка, но он может быть системным (общим для нескольких процессов).
Семафора делает то же самое , как взаимная блокировку , но позволяет й количество потоков , чтобы войти, это может быть использовано, например , чтобы ограничить число процессоров, Ио~d или баран ресурсоемких задач , выполняющиеся в то же время.
Более подробный пост о различиях между мьютексом и семафором читайте здесь .
У вас также есть блокировки чтения / записи, которые позволяют неограниченное количество читателей или 1 писатель в любой момент времени.
источник
Есть много заблуждений относительно этих слов.
Это из предыдущего поста ( https://stackoverflow.com/a/24582076/3163691 ), который отлично подходит здесь:
1) Критический раздел = Пользовательский объект, используемый для разрешения выполнения только одного активного потока из множества других в одном процессе . Другие не выбранные потоки (@ получение этого объекта) помещаются в спящий режим .
Нет возможности межпроцессного, очень примитивный объект.
2) Семафор Mutex (также известный как Mutex) = объект ядра, используемый для разрешения выполнения только одного активного потока из множества других, среди различных процессов . Другие не выбранные потоки (@ получение этого объекта) помещаются в спящий режим . Этот объект поддерживает владение потоком, уведомление о прекращении потока, рекурсию (множественные вызовы «получения» из одного потока) и «предотвращение инверсии приоритетов».
Межпроцессная возможность, очень безопасная в использовании, своего рода объект синхронизации «высокого уровня».
3) Подсчет семафора (он же семафор) = объект ядра, используемый для разрешения выполнения группы активных потоков из множества других. Другие не выбранные потоки (@ получение этого объекта) помещаются в спящий режим .
Однако возможность межпроцессного использования не очень безопасна, поскольку в ней отсутствуют следующие атрибуты 'mutex': уведомление о завершении потока, рекурсия ?, 'предотвращение инверсии приоритета'? И т. Д.].
4) А теперь, говоря о спин-замках, сначала несколько определений:
Критическая область = область памяти, совместно используемая двумя или более процессами.
Lock = Переменная, значение которой разрешает или запрещает вход в «критическую область». (Это может быть реализовано как простой «логический флаг»).
Ожидание при занятости = постоянное тестирование переменной до появления какого-либо значения.
В заключение:
Spin-lock (также известный как Spinlock) = блокировка, которая использует ожидание занятым . (Получение блокировки производится с помощью xchg или аналогичных атомарных операций ).
[Нет спящего потока, в основном используется только на уровне ядра. Неэффективный для кода уровня пользователя.
В качестве последнего комментария я не уверен, но могу поспорить с вами, что большие первые синхронизирующие объекты (# 1, # 2 и # 3), указанные выше, используют этого простого зверя (# 4) как часть своей реализации.
Хорошего дня!.
Ссылки:
-Концепции реального времени для встраиваемых систем Цин Ли с Кэролайн Яо (CMP Books).
Современные операционные системы (3-е место) Эндрю Таненбаума (Pearson Education International).
-Программирование приложений для Microsoft Windows (4-е) от Джеффри Рихтера (Microsoft Programming Series).
Кроме того, вы можете взглянуть на: https://stackoverflow.com/a/24586803/3163691
источник
Большинство проблем можно решить с помощью (i) просто блокировок, (ii) просто семафоров, ... или (iii) комбинации обоих! Как вы, возможно, обнаружили, они очень похожи: оба препятствуют состязаниям , оба имеют
acquire()
/release()
операции, оба приводят к блокировке / подозрению на ноль или более потоков ... Действительно, принципиальное различие заключается исключительно в том, как они блокируют и разблокируют .Для обеих блокировок / семафоров попытка вызова,
acquire()
когда примитив находится в состоянии 0, приводит к приостановке вызывающего потока. Для блокировок - попытки получить блокировку в состоянии 1 успешны. Для семафоров - попытки получить блокировку в состояниях {1, 2, 3, ...} успешны.Для блокировок в состоянии 0, если тот же поток, который ранее вызывал
acquire()
, теперь вызывает release, то релиз успешен. Если другой поток попробовал это - дело за реализацией / библиотекой относительно того, что происходит (обычно попытка игнорируется или выдается ошибка). Для семафоров в состоянии 0 любой поток может вызвать release, и он будет успешным (независимо от того, какой поток использовался ранее, чтобы перевести семафор в состояние 0).Из предыдущего обсуждения мы видим, что у замков есть понятие владельца (единственный поток, который может вызвать release, является владельцем), в то время как у семафоров нет владельца (любой поток может вызывать release на семафоре).
Что вызывает много путаницы, так это то, что на практике они представляют собой множество вариаций этого определения высокого уровня.
Важные варианты для рассмотрения :
acquire()
/release()
называться? - [Различная массово ]Это зависит от вашей книги / лектора / языка / библиотеки / окружения.
Вот краткий обзор того, как некоторые языки отвечают на эти детали.
C, C ++ ( pthreads )
pthread_mutex_t
. По умолчанию они не могут использоваться совместно с другими процессами (PTHREAD_PROCESS_PRIVATE
), однако мьютексы имеют атрибут pshared . Если установлено, то мьютекс является общим для процессов (PTHREAD_PROCESS_SHARED
).sem_t
. Подобно мьютексам, семафоры могут быть разделены между потоками многих процессов или могут быть приватными для потоков одного отдельного процесса. Это зависит от аргумента pshared, предоставленногоsem_init
.питон ( threading.py )
threading.RLock
) в основном такой же , как C / C ++pthread_mutex_t
с. Оба являются реентерабельными . Это означает, что они могут быть разблокированы только тем потоком, который его заблокировал. Это тот случай, когдаsem_t
семафоры,threading.Semaphore
семафоры иtheading.Lock
блокировки не являются реентерабельными - это тот случай, когда любой поток может выполнить разблокировку / блокировку семафора.threading.Semaphore
) в основном такой же , какsem_t
. Хотя сsem_t
помощью, очередь идентификаторов потоков используется для запоминания порядка, в котором потоки блокировались при попытке заблокировать его, пока он заблокирован. Когда поток разблокирует семафор, в качестве нового владельца выбирается первый поток в очереди (если он есть). Идентификатор потока удаляется из очереди, и семафор снова блокируется. Однако сthreading.Semaphore
помощью набора используется вместо очереди, поэтому порядок, в котором потоки блокировались, не сохраняется - любой поток в наборе может быть выбран следующим владельцем.Java ( java.util.concurrent )
java.util.concurrent.ReentrantLock
) в основном так же , как C / C ++pthread_mutex_t
«s и Питонthreading.RLock
в том , что она также реализует возвратный замок. Совместное использование блокировок между процессами в Java сложнее, поскольку JVM выступает в качестве посредника. Если поток пытается разблокировать блокировку, которой он не владеет, создаетсяIllegalMonitorStateException
исключение.java.util.concurrent.Semaphore
), в основном такой же , какsem_t
иthreading.Semaphore
. Конструктор для семафоров Java принимает логический параметр fairness, который управляет использованием набора (false) или очереди (true) для хранения ожидающих потоков.Теоретически семафоры часто обсуждаются, но на практике семафоры используются не так часто. Семафор содержит состояние только одного целого числа, поэтому часто он довольно негибкий, и многие нужны сразу, что вызывает трудности в понимании кода. Кроме того, тот факт, что любой поток может выпустить семафор, иногда нежелателен. Вместо этого используются более объектно-ориентированные / высокоуровневые примитивы / абстракции синхронизации, такие как «переменные условия» и «мониторы».
источник
Взгляните на учебник по многопоточности Джона Копплина.
В разделе « Синхронизация между потоками» он объясняет различия между событием, блокировкой, мьютексом, семафором, ожидаемым таймером.
источник
Я постараюсь покрыть это примерами:
Блокировка. Одним из примеров, в котором вы будете использовать,
lock
будет общий словарь, в который добавляются элементы (которые должны иметь уникальные ключи).Блокировка гарантирует, что один поток не войдет в механизм кода, который проверяет наличие элемента в словаре, в то время как другой поток (который находится в критическом разделе) уже прошел эту проверку и добавляет элемент. Если другой поток пытается ввести заблокированный код, он будет ждать (будет заблокирован), пока объект не будет освобожден.
Семафор: Допустим, у вас есть пул соединений, тогда один поток может зарезервировать один элемент в пуле, ожидая, пока семафор установит соединение. Затем он использует соединение, а когда работа завершена, освобождает соединение, освобождая семафор.
Пример кода, который я люблю, - это пример баунсера, который дал @Patric .
Мьютекс В значительной степени
Semaphore(1,1)
и часто используется во всем мире (в других случаях применениеlock
более целесообразно). Можно использовать globalMutex
при удалении узла из глобально доступного списка (последнее, что вы хотите, чтобы другой поток делал что-то, пока вы удаляете узел). Когда вы получите,Mutex
если другой поток попытается получить одно иMutex
то же, он будет переведен в спящий режим, пока тот же поток, который получил его, неMutex
освободит его.Хороший пример создания глобального мьютекса - @deepee
тогда используйте как:
Надеюсь, это сэкономит вам время.
источник
В Википедии есть отличный раздел о различиях между семафорами и мьютексами :
источник
Насколько я понимаю, мьютекс предназначен только для использования в одном процессе, но во многих его потоках, тогда как семафор может использоваться в нескольких процессах и в соответствующих наборах потоков.
Кроме того, мьютекс является двоичным (он либо заблокирован, либо разблокирован), тогда как семафор имеет понятие подсчета или очередь из нескольких запросов на блокировку и разблокировку.
Может ли кто-нибудь проверить мое объяснение? Я говорю в контексте Linux, в частности Red Hat Enterprise Linux (RHEL) версии 6, которая использует ядро 2.6.32.
источник
Использование программирования на C для варианта Linux в качестве базового примера.
Замок:
• Обычно очень простой двоичный файл конструкции, либо заблокированный, либо разблокированный.
• Нет концепции владения потоком, приоритета, последовательности и т. Д.
• Обычно спин-блокировка, когда поток постоянно проверяет наличие блокировок.
• Обычно полагается на атомарные операции, например, «Тестировать и устанавливать», сравнивать и менять, извлекать и добавлять и т. Д.
• Обычно требуется аппаратная поддержка для атомарной работы.
Файловые блокировки:
• Обычно используется для координации доступа к файлу через несколько процессов.
• Несколько процессов могут удерживать блокировку чтения, однако, когда любой отдельный процесс удерживает блокировку записи, никакому другому процессу не разрешается получать блокировку чтения или записи.
• Пример: flock, fcntl и т. Д.
мьютекс:
• Вызовы функции Mutex обычно работают в пространстве ядра и приводят к системным вызовам.
• Используется концепция собственности. Только поток, который в настоящее время содержит мьютекс, может разблокировать его.
• Мьютекс не является рекурсивным (Исключение: PTHREAD_MUTEX_RECURSIVE).
• Обычно используется в ассоциации с переменными условия и передается в качестве аргументов, например, pthread_cond_signal, pthread_cond_wait и т. Д.
• В некоторых системах UNIX мьютекс может использоваться несколькими процессами, хотя это может быть не реализовано во всех системах.
Семафор:
• Это целое число, поддерживаемое ядром, значения которого не могут опускаться ниже нуля.
• Может использоваться для синхронизации процессов.
• Значение семафора может быть установлено на значение больше 1, и в этом случае значение обычно указывает количество доступных ресурсов.
• Семафор, значение которого ограничено 1 и 0, называется двоичным семафором.
источник
Supporting ownership
,maximum number of processes share lock
А такжеmaximum number of allowed processes/threads in critical section
три основных фактора , которые определяют имя / тип параллельного объекта с общим названиемlock
. Поскольку значения этих факторов являются двоичными (имеют два состояния), мы можем суммировать их в 3 * 8 правдоподобной таблице.Не стесняйтесь редактировать или расширять эту таблицу, я разместил ее как таблицу ascii, чтобы ее можно было редактировать :)
источник