> Как работает дедлок и как его избежать (iOS, Swift)
Уровень: senior · Роль: mobile · Категория: Технические вопросы
Компании: Axel Pro
Стек: iOS, Swift
> Пример ответа
Дедлок (взаимная блокировка) в iOS-разработке на Swift возникает, когда два или более потока (или очереди) ожидают освобождения ресурсов, захваченных друг другом, и ни один из них не может продолжить выполнение. Классический пример - использование семафоров или блокировок (NSLock, os_unfair_lock) в сочетании с GCD.
Как возникает дедлок:
- Поток A захватывает ресурс 1 и ждет ресурс 2.
- Поток B захватывает ресурс 2 и ждет ресурс 1.
- Оба потока блокируются навсегда.
Пример на Swift:
SWIFTlet lock1 = NSLock()let lock2 = NSLock()DispatchQueue.global().async {lock1.lock()sleep(1) // имитация работыlock2.lock()print("Поток 1 выполнен")lock2.unlock()lock1.unlock()}DispatchQueue.global().async {lock2.lock()sleep(1)lock1.lock()print("Поток 2 выполнен")lock1.unlock()lock2.unlock()}
Здесь оба потока зависнут.
Как избежать дедлока:
- Соблюдать порядок захвата блокировок - всегда захватывать ресурсы в одном и том же порядке (например, сначала lock1, потом lock2). Это самый надежный способ.
- Использовать os_unfair_lock (или NSLock с тайм-аутом) - но в Swift нет встроенного тайм-аута для NSLock, поэтому лучше избегать сложных иерархий.
- Применять GCD вместо ручных блокировок - использовать последовательные очереди (DispatchQueue) или барьеры (barrier) для синхронизации доступа к данным. Например, через
syncна serial queue. - Использовать async/await (Swift Concurrency) - с акторами (actor) дедлоки практически исключены, так как акторы автоматически управляют доступом к своему состоянию.
- Избегать вложенных блокировок - если возможно, перепроектировать код так, чтобы не требовалось захватывать несколько ресурсов одновременно.
В iOS-разработке чаще всего дедлоки возникают при неправильном использовании DispatchQueue.main.sync из фоновой очереди (если main уже заблокирован) или при смешивании семафоров с асинхронными вызовами. Лучшая практика - минимизировать ручные блокировки и отдавать предпочтение высокоуровневым абстракциям Swift Concurrency.
> Похожие задачи по mobile
Какие механизмы синхронизации существуют для решения проблем многопоточности
Какие средства синхронизации потоков существуют: mutex, semaphore, NSLock
На каких архитектурах писали и какие плюсы и минусы вы видите
Что копируется, а что передается по ссылке в Swift
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью