Взаимные блокировки в GCD
Вопрос
Какие взаимные блокировки бывают в GCD и как их избежать?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
`sync` на текущую serial-очередь (в том числе `main.sync` с главного)
Две serial-очереди делают `sync` друг на друга
`group.wait()` или `semaphore.wait()` на главном потоке, когда завершение тоже нужно главному
Исчерпание потоков при массовой блокировке
Профилактика: `async` по умолчанию, не держать блокировки при вызове внешнего кода, Swift Concurrency
Что могут спросить следом
- Как понять, что ты уже на нужной очереди?
- Чем
dispatchPreconditionпомогает в отладке?
Разбор
Самый частый deadlock: sync на ту же последовательную очередь, в которой ты уже находишься. Например, DispatchQueue.main.sync с главного потока или вложенный queue.sync внутри блока этой же очереди. Вариант посложнее: очередь A делает sync на B, а B в это время sync на A. Ещё сценарий: на главном потоке group.wait(), а completion сетевого запроса тоже хочет выполниться на главной очереди. И отдельная беда: сотни блокирующих задач исчерпывают пул потоков, и очереди стоят. Избегаю так: по умолчанию async, sync только на свою приватную очередь и только снаружи неё, dispatchPrecondition(condition: .onQueue(q)) в отладке, чтобы ловить вызовы не с той очереди. А новый код пишу на async/await, где компилятор не даст заблокировать актор так просто.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «GCD и OperationQueue»
- Асинхронная Operation
- Барьер для потокобезопасного кеша
- Инверсия приоритетов
- DispatchSemaphore для ограничения параллельности
- DispatchWorkItem и отмена
- Как дождаться нескольких запросов в GCD
- Задача на Swift: операции с зависимостями и критический путь
- Задача на Swift: OperationQueue с ограничением параллельности