Мьютекс ничего не блокирует. Вы просто используете мьютекс, чтобы сообщить другим частям вашего кода, что они должны учитывать то, что вы решите, что необходимо защитить от доступа одновременно несколькими потоками, чтобы быть недоступным на данный момент.
Вы могли бы думать о мьютексе как о чем-то вроде логического okToModify
. Всякий раз, когда вы хотите что-то отредактировать, вы проверяете, является ли okToModify
true
. Если это так, вы установите его на false
(не позволяя другим потокам изменять его), измените его, затем установите okToModify
обратно на true
, чтобы сообщить другим потокам, что вы закончили, и дать им возможность изменить :
// WARNING! This code doesn't actually work as a lock!
// it is just an example of the concept.
struct LockedInt {
bool okToModify; // This would be your mutex instead of a bool.
int integer;
};
struct LockedInt myLockedInt = { true, 0 };
...
while (myLockedInt.okToModify == false)
; // wait doing nothing until whoever is modifying the int is done.
myLockedInt.okToModify = false; // Prevent other threads from getting out of while loop above.
myLockedInt.integer += 1;
myLockedInt.okToModify = true; // Now other threads get out of the while loop if they were waiting and can modify.
Тогда как l oop и okToModify = false
выше - это, в основном, блокировка мьютекса, а okToModify = true
- это разблокировка мьютекса.
Теперь, почему нам нужны мьютексы и мы не используем логические выражения? Потому что поток может быть запущен одновременно с этими тремя строками выше. Код для блокировки мьютекса фактически гарантирует, что ожидание okToModify
становится true
и установка okToModify = false
происходят в одном go, и поэтому никакой другой поток не может попасть "между строк", например, используя специальная инструкция машинного кода, называемая «сравнить и обменять».
Так что do not использует булевы значения вместо мьютексов , но вы можете думайте о мьютексе как о специальном, поточно-ориентированном логическом значении.