В чем отличие семафора от мьютекса
Что проверяют
Понимаете ли вы разницу глубже, чем «один поток против нескольких». Главное здесь владение блокировкой и то, как оно сказывается на приоритетах потоков. Следом в iOS обычно спрашивают, можно ли использовать DispatchSemaphore вместе с async/await.
Как отвечать
- мьютекс: взаимное исключение с владельцем. Какой поток захватил, тот и отпускает. В iOS это
NSLock,NSRecursiveLock,os_unfair_lock(удобнее черезOSAllocatedUnfairLockс iOS 16) иMutexиз фреймворка Synchronization, доступный с iOS 18; - семафор: счётчик разрешений без владельца.
DispatchSemaphore(value: 3)пускает три задачи одновременно,wait()уменьшает счётчик и ждёт, если он ушёл в минус,signal()увеличивает его и может вызываться из любого потока.
Отсюда назначение. Мьютекс защищает критическую секцию, например словарь кэша, к которому ходят из разных очередей. Семафор ограничивает параллелизм (не больше трёх загрузок одновременно) или служит сигналом «событие произошло» между потоками.
Бинарный семафор не равен мьютексу. Раз у семафора нет владельца, система не знает, чей приоритет повышать, когда высокоприоритетный поток ждёт низкоприоритетный. Thread Performance Checker в Xcode предупреждает о таком ожидании. У os_unfair_lock владелец известен, и приоритет передаётся.
В Swift Concurrency оба механизма почти не нужны: общее изменяемое состояние прячут в actor, а ограничение параллелизма делают через TaskGroup, добавляя новую задачу по мере завершения предыдущих. Вызов semaphore.wait() внутри async-функции блокирует поток кооперативного пула, и приложение может встать целиком.
Где спотыкаются
Говорят, что мьютекс это семафор со значением 1. А владелец и инверсия приоритетов как раз то, что обычно хотят услышать.
Ждут на semaphore.wait() в главном потоке ответа, который приходит в главную очередь. Главный поток заблокирован, колбэк выполниться не может, получается взаимная блокировка.
Нарушают баланс wait() и signal(). Если семафор освобождается из памяти, когда его значение меньше начального, libdispatch роняет приложение с сообщением о семафоре, удалённом во время использования.