Ответ
Мьютекс (от англ. mutual exclusion — взаимное исключение) — это примитив синхронизации, который гарантирует эксклюзивный доступ к общему ресурсу для нескольких потоков. Он решает проблему состояния гонки (race condition), когда результат выполнения программы зависит от непредсказуемого порядка выполнения потоков.
Принцип работы:
- Поток, которому нужен доступ к ресурсу, пытается «захватить» мьютекс.
- Если мьютекс свободен, поток захватывает его, выполняет работу с ресурсом (входит в критическую секцию) и затем «освобождает» мьютекс.
- Если мьютекс уже захвачен другим потоком, текущий поток блокируется и ожидает его освобождения.
Пример на Python с threading.Lock:
import threading
# Общий ресурс
counter = 0
# Мьютекс для защиты ресурса
lock = threading.Lock()
def increment():
global counter
for _ in range(100000):
# with автоматически захватывает и освобождает мьютекс
with lock:
counter += 1
threads = [threading.Thread(target=increment) for _ in range(10)]
for t in threads:
t.start()
for t in threads:
t.join()
# Без мьютекса результат был бы непредсказуем
print(f"Итоговое значение: {counter}") # Гарантированно 1000000
Использование мьютекса обеспечивает атомарность операций в критической секции, делая код потокобезопасным.
Ответ 18+ 🔞
А, слушай, про мьютексы, да? Ну это такая штука, чтобы потоки друг другу в тарелку не срали, когда к одному и тому же куску памяти лезут. Взаимное исключение, блядь, как с одним сортиром на десять человек — пока один сидит и срёт, остальные ждут снаружи, терпят, блядь, скрепя зубами.
Вот представь: у тебя есть переменная counter, и десять потоков её одновременно увеличивают. Без мьютекса — это пиздец, бардак и состояние гонки. Один поток прочитал значение, второй в это же время его же прочитал, оба прибавили единичку и записали обратно. И вместо двух прибавлений получилось одно, понимаешь? Всё, пиши пропало, результат — хуйня полная, а не миллион.
А с мьютексом — красота. Он как вышибала у входа в критическую секцию: «Ты куда, сука? Ресурс занят! Стоять, ждать!». Поток захватил замок, сделал свои делишки, отпустил — следующий заходит. Порядок, блядь, а не анархия.
Смотри, как это на Питоне выглядит, там просто до безобразия:
import threading
# Общий ресурс
counter = 0
# Мьютекс для защиты ресурса
lock = threading.Lock()
def increment():
global counter
for _ in range(100000):
# with автоматически захватывает и освобождает мьютекс
with lock:
counter += 1
threads = [threading.Thread(target=increment) for _ in range(10)]
for t in threads:
t.start()
for t in threads:
t.join()
# Без мьютекса результат был бы непредсказуем
print(f"Итоговое значение: {counter}") # Гарантированно 1000000
Видишь этот with lock:? Это гениально, ёпта. Вошёл — сделал — вышел, и даже если посередине исключение выскочит, мьютекс всё равно отпустится. Не то что в каких-то других языках, где можно забыть его разлочить и потом всю систему повисшую искать, блядь.
Вот и вся магия. Захватил — поработал — отпустил. Атомарность, потокобезопасность, и все довольны. Главное — не забудь его отпустить, а то остальные потоки так и будут висеть в ожидании, пока их по таймауту не убьёт.