Вопрос проверяет понимание причин deadlock и умение анализировать порядок выполнения задач в GCD.
Deadlock возникает, когда поток ждет завершения задачи, которая не может начаться. Чаще всего это происходит при вызове sync на той же очереди, в которой уже выполняется код. Очередь ждет сама себя. В результате выполнение останавливается навсегда. Это одна из самых частых ошибок при работе с GCD.
Deadlock — это ситуация, когда выполнение кода полностью останавливается из-за взаимного ожидания.
Перед тем как приводить причины, рассмотрим базовый пример:
DispatchQueue.main.sync {
// код
}
Если этот код вызывается уже на main queue, происходит deadlock.
Serial queue выполняет одну задачу за раз
Main queue — последовательная очередь.
sync блокирует текущий поток
Текущий поток ждет завершения блока.
Очередь занята текущей задачей
Новая задача не может начаться, пока не завершится текущая.
Взаимное ожидание
Поток ждет очередь, очередь ждет поток.
Взаимные sync-вызовы между очередями
Одна очередь синхронно ждет другую, а та — первую.
Использование sync внутри lock-подобной логики
Неправильная комбинация семафоров и sync.
Вызов sync в callback, который уже удерживает ресурс
не вызывать sync на текущей очереди
использовать async, если нет жесткой необходимости
четко понимать, на какой очереди выполняется код
Deadlock при dispatch sync возникает из-за блокировки потока и невозможности очереди выполнить ожидаемую задачу.