← Назад к вопросам

Какие приоритеты у очередей?

2.0 Middle🔥 81 комментариев
#Многопоточность и асинхронность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Приоритеты очередей в GCD (Grand Central Dispatch)

В Grand Central Dispatch (GCD) для очередей определены следующие приоритеты (или, более корректно, классы качества обслуживания). Начиная с iOS 8 и macOS 10.10, вместо старых приоритетов (DISPATCH_QUEUE_PRIORITY_*) используются QoS (Quality of Service) классы, которые лучше отражают цели выполняемой работы и позволяют системе более оптимально управлять ресурсами.

Основные QoS классы

GCD предоставляет шесть основных классов QoS, от наивысшего до наименьшего приоритета:

  1. userInteractive – наивысший приоритет.
    *   Используется для задач, напрямую связанных с взаимодействием с пользователем, таких как:
        *   Анимации UI.
        *   Обработка событий основного потока (`main thread`).
        *   Обновление интерфейса.
    *   Задачи должны выполняться **мгновенно**, чтобы обеспечить плавный пользовательский опыт.

  1. userInitiated – высокий приоритет.
    *   Для задач, начатых пользователем, которые требуют немедленного результата, но не блокируют UI.
    *   Примеры:
        *   Открытие документа.
        *   Обработка действий пользователя (нажатие кнопки, которая запускает вычисления).
    *   Пользователь ожидает результат, но готов к небольшой задержке.

  1. default – средний (дефолтный) приоритет.
    *   Этот класс используется по умолчанию, если QoS не указан явно.
    *   Применяется для задач, которые не относятся напрямую к активности пользователя и не критичны по времени.

  1. utility – низкий приоритет.
    *   Для длительных задач, где пользователь ожидает результат, но не требует его немедленно.
    *   Примеры:
        *   Загрузка данных из сети.
        *   Вычисления с прогнозом прогресса (например, обработка изображений).
    *   Система может балансировать энергоэффективность и производительность.

  1. background – наименьший приоритет.
    *   Для задач, которые не видимы для пользователя и не требуют его внимания.
    *   Примеры:
        *   Индексирование данных.
        *   Синхронизация в фоне.
        *   Очистка кэша.
    *   Система будет максимально оптимизировать такие задачи по энергопотреблению и тепловому режиму.

  1. unspecified – отсутствие указанного QoS.
    *   Указывает на отсутствие информации о QoS.
    *   Система может определить приоритет по контексту (например, по QoS потока-создателя). Использовать следует осторожно.

Создание очереди с указанием QoS

При создании собственной dispatch очереди вы можете указать нужный класс QoS.

import Dispatch

// Создание serial (private) очереди с высоким приоритетом (userInitiated)
let highPriorityQueue = DispatchQueue(label: "com.example.highPriorityQueue",
                                      qos: .userInitiated)

// Создание concurrent очереди с низким приоритетом (utility)
let lowPriorityConcurrentQueue = DispatchQueue(label: "com.example.lowPriorityConcurrentQueue",
                                               qos: .utility,
                                               attributes: .concurrent)

// Выполнение задачи на созданной очереди
highPriorityQueue.async {
    print("Выполняем важную задачу, начатую пользователем")
}

Приоритеты и глобальные очереди

Глобальные очереди также соответствуют этим QoS классам. Их можно получить через DispatchQueue.global(qos:).

// Получение глобальной concurrent очереди с приоритетом utility
let globalUtilityQueue = DispatchQueue.global(qos: .utility)

globalUtilityQueue.async {
    // Задача для выполнения в фоне с низким приоритетом
    downloadDataFromServer()
}

Важные принципы и рекомендации

  • Приоритет наследования: Если вы не указываете QoS при создании задачи (async), система может определить его по контексту (например, по QoS текущей очереди). Это называется priority inheritance.
  • Main Queue: Главная очередь (DispatchQueue.main) имеет приоритет userInteractive. Все операции UI должны выполняться на ней.
  • Не злоупотреблять высокими приоритетами: Необоснованное использование userInteractive для задач, не связанных с UI, может привести к снижению общей производительности и плавности интерфейса, так как система будет тратить ресурсы на менее важные операции.
  • Балансировка: Правильное назначение QoS помогает системе оптимизировать работу устройства: повысить производительность для критичных задач и снизить энергопотребление для фоновых.

Итог: Использование QoS классов вместо старых приоритетов позволяет более точно и эффективно классифицировать задачи в многозадачной системе iOS/macOS, что напрямую влияет на пользовательский опыт, производительность и энергоэффективность приложения. Выбор правильного класса — важная часть оптимизации работы с многопоточностью в GCD.