Будет ли deadlock при синхронном вызове задачи на main queue из глобальной очереди
Что проверяют
Понимаете ли вы, откуда берётся deadlock, или помните только фразу «sync на main опасен». Правильный ответ: сам по себе нет. Дальше интервьюер почти всегда спрашивает, при каком условии всё-таки зависнет и что будет при DispatchQueue.main.sync с главного потока.
Как отвечать
Начните с механики. sync ставит блок в очередь и блокирует вызывающий поток, пока блок не выполнится. В коде DispatchQueue.global().async { DispatchQueue.main.sync { ... } } фоновый поток встаёт и ждёт. Главная очередь при этом свободна: как только run loop дойдёт до блока, тот выполнится, фоновый поток проснётся и продолжит. Никто не ждёт по кругу, значит deadlock нет.
Deadlock требует цикла ожидания:
- главный поток ждёт фон: он сделал
global().sync,group.wait()илиsemaphore.wait()на задачу, внутри которой стоитmain.sync. Главный ждёт фоновую задачу, та ждёт главный; main.syncс главного потока: очередь ждёт сама себя. libdispatch это распознаёт и роняет приложение с сообщениемdispatch_sync called on queue already owned by current thread;- то же с любой последовательной очередью:
serialQueue.syncизнутри блока этой же очереди.
Хорошо добавить, почему так всё равно не пишут. Фоновый поток простаивает, пока главный занят, а код становится хрупким: стоит кому-то вызвать его с главного потока или добавить ожидание, и приложение зависнет. Обычный путь: DispatchQueue.main.async или в Swift Concurrency await MainActor.run { }, где задача приостанавливается, а поток не блокируется. Для самопроверки есть dispatchPrecondition(condition: .onQueue(.main)).
Где спотыкаются
Отвечают «да, будет deadlock», перепутав этот случай с вызовом main.sync с главного потока.
Не могут назвать условие. Без слов «цикл ожидания» ответ звучит заученно, и следующий вопрос с чуть изменённым кодом ставит в тупик.
Путают две оси. sync и async говорят о том, ждёт ли вызывающий поток, а последовательность и параллельность относятся к самой очереди. Отсюда ответы вроде «главная очередь последовательная, значит sync на неё блокирует навсегда».