Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: GCD, serial queue, sync, dispatch, deadlock

Что произойдет при вызове sync внутри serial queue?

Вопрос проверяет понимание работы последовательных (serial) очередей в GCD (Grand Central Dispatch) и их взаимодействия с синхронными (sync) операциями.

Короткий ответ

При вызове `sync` внутри serial queue задача будет добавлена в эту же очередь и выполнится немедленно, блокируя текущий поток до завершения. Если вызов `sync` выполняется из задачи, которая уже работает на этой же serial queue, и мы пытаемся отправить новую задачу синхронно в ту же очередь, это приведёт к взаимной блокировке (deadlock), потому что очередь будет ждать завершения текущей задачи, а текущая задача ждёт запуска новой.

Длинный ответ

Serial queue (последовательная очередь) в GCD гарантирует, что задачи выполняются строго одна за другой. Метод dispatch_sync (или sync в Swift) отправляет задачу в очередь и блокирует текущий поток до её завершения.

Обычный случай

Если вызов sync происходит извне serial queue (например, из main thread или другой очереди), задача будет поставлена в конец serial queue и выполнится, как только очередь освободится. Текущий поток будет заблокирован на время выполнения этой задачи.

let serialQueue = DispatchQueue(label: "com.example.serial")
serialQueue.async {
    print("Task 1")
}
// Вызов из main thread
serialQueue.sync {
    print("Task 2") // Выполнится после Task 1
}
print("После sync") // Напечатается после завершения Task 2

Случай deadlock

Проблема возникает, когда вызов sync выполняется из задачи, которая уже работает на этой же serial queue. Поскольку очередь последовательная, она не может начать новую задачу, пока не завершит текущую. Но текущая задача ждёт, пока новая задача запустится и завершится. Это взаимное ожидание приводит к deadlock.

let serialQueue = DispatchQueue(label: "com.example.serial")
serialQueue.async {
    // Эта задача уже выполняется на serialQueue
    serialQueue.sync {
        print("Этот код никогда не выполнится")
    }
    print("Это тоже не выполнится")
}

В этом примере внешняя асинхронная задача занимает serial queue. Внутри неё мы пытаемся синхронно отправить другую задачу в ту же очередь. Очередь ждёт завершения внешней задачи, но внешняя задача ждёт запуска внутренней — deadlock.

Практическое применение и вывод

Понимание этого поведения критично для избежания deadlock в многопоточном коде. Serial queues часто используются для синхронизации доступа к общим ресурсам. Синхронные вызовы в них полезны, когда нужно дождаться результата, но их нужно использовать осторожно, избегая вызовов в ту же очередь изнутри.

Итог: Вызов sync внутри serial queue безопасен, если он выполняется не из задачи, работающей на этой же очереди. В противном случае это приводит к deadlock. Используйте async или убедитесь, что вызов идёт с другого потока/очереди.

  • Аватар

    iOS Guru

    Roman Isakov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

Ключевые слова

#GCD

#serial queue

#sync

#dispatch

#deadlock

Подпишись на iOS Developer в телеграм

  • Аватар

    iOS Guru

    Roman Isakov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.