Мьютексы и семафоры: назначение и различие

Оба механизма (мьютекс и семафор) используются для синхронизации потоков или процессов в многопоточной среде, но имеют разное назначение и поведение.

1. Мьютекс (Mutex, Mutual Exclusion)

Назначение:

  • Обеспечивает взаимное исключение — только один поток может владеть мьютексом в данный момент.
  • Используется для защиты критических секций (участков кода, где обрабатываются общие данные).

Особенности:

  • Бинарный: может находиться в одном из двух состояний — заблокирован или разблокирован.
  • Владелец: только поток, который заблокировал мьютекс, может его разблокировать.
  • Рекурсивность: в некоторых реализациях (например, pthread_mutex) может быть рекурсивным (один поток может захватывать его несколько раз).
  • Аналогия: Мьютекс — как ключ от туалета: только один человек (поток) может им владеть, и он должен вернуть ключ, чтобы другие смогли войти.

2. Семафор (Semaphore)

Назначение:

  • Ограничивает количество потоков, которые могут одновременно выполнять определенный участок кода.
  • Может использоваться для управления доступом к ресурсам с ограниченной ёмкостью (например, пул соединений к БД).

Особенности:

  • Счётчик: семафор имеет счётчик, который уменьшается при wait() (захвате) и увеличивается при post() (освобождении).
  • Не имеет владельца: любой поток может освободить семафор (в отличие от мьютекса).
  • Типы:
    • Бинарный семафор (аналогичен мьютексу, но без владельца).
    • Счётный семафор (разрешает доступ N потокам одновременно).
  • Аналогия: Семафор — как пропуск на парковку: есть ограниченное количество мест (N), и когда места заканчиваются, новые машины (потоки) ждут, пока кто-то не освободит место.

Когда что использовать?

  • Мьютекс — когда нужно гарантировать, что только один поток работает с ресурсом (например, изменение общей переменной).
  • Семафор — когда нужно ограничить доступ к ресурсу для N потоков (например, пул соединений или ограничение параллельных задач).

Пример:

  • Если у вас есть общий буфер, куда пишут несколько потоков, нужен мьютекс.
  • Если у вас есть пул из 10 подключений к БД и нужно ограничить их использование, подойдёт семафор со значением 10.

Вывод

Мьютекс — для эксклюзивного доступа, семафор — для ограничения параллелизма. 🚀