Что произойдет, если две мухи блокируют мьютекс одновременно? - PullRequest
4 голосов
/ 10 сентября 2011

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

Параллельно работают два потока, и они пытаются заблокироватьмьютекс одновременно.

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

Спасибо за любую помощь

Ответы [ 2 ]

8 голосов
/ 10 сентября 2011

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

Семантика мьютекса / блокировки!убедитесь, что за один раз вызов блокировки может выполняться только один поток.Первый поток, который достигает вызова, получает блокировку мьютекса.Любые последующие потоки будут блокироваться при вызове mutex / lock!пока поток, которому принадлежит блокировка, не снимет блокировку с помощью mutex / unlock!.

С точки зрения того, как это можно реализовать, посмотрите test-and-set .

В информатике инструкция «проверить и установить» - это инструкция, используемая для записи в ячейку памяти и возврата ее старого значения в виде одной атомарной (т. Е. Непрерывной) операции.Если несколько процессов могут обращаться к одной и той же памяти, и если процесс в настоящее время выполняет тестирование и настройку, никакой другой процесс не может начать другой тестирование и установку, пока не будет выполнен первый процесс.Процессоры могут использовать инструкции тестирования и установки, предлагаемые другими электронными компонентами, такими как двухпортовая ОЗУ;Процессоры также могут сами предлагать команду проверки и установки.

Вызывающий процесс получает блокировку, если старое значение было 0. Он вращает запись 1 в переменную до тех пор, пока это не произойдет.

6 голосов
/ 10 сентября 2011

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

Одна такая операция - xchg (exchange) в x86архитектура.Например, xchg eax, [ebp] прочитает значение по адресу ebp, запишет значение в eax по адресу ebp, а затем установит eax в считанное значение, гарантируя, что эти действия не будут чередоватьсяс одновременным чтением и записью по этому адресу.

Теперь вы можете реализовать мьютекс.Для блокировки загрузите 1 в eax, замените eax значением мьютекса и посмотрите на eax.Если это 1, он уже заблокирован, поэтому вы можете захотеть поспать и повторить попытку позже.Если это 0, вы просто заблокировали мьютекс.Чтобы разблокировать, просто введите значение 0 в мьютекс.

Обратите внимание, что здесь я замаскирую важные детали.Например, x86 xchg является достаточно атомарным для преимущественной многозадачности на одном процессоре.Когда вы разделяете память между несколькими процессорами (например, в многоядерной системе), этого будет недостаточно, если вы не используете префикс lock (например, lock xchg eax, [ebp], а не xchg eax, [ebp]), что гарантирует, что только один процессор может получить доступ к этой памяти во время выполнения инструкции .

...