Что такое барьер (dispatch barrier) в GCD?

«Что такое барьер (dispatch barrier) в GCD?» — вопрос из категории Многопоточность, который задают на 23% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Барьер (Dispatch Barrier) — это задача в Grand Central Dispatch (GCD), которая при выполнении на concurrent очереди действует как точка синхронизации, обеспечивая эксклюзивный доступ.

Принцип работы:

На concurrent очереди (attributes: .concurrent):

  1. Задачи, поставленные до барьерной задачи, выполняются параллельно.
  2. Барьерная задача ждет завершения всех предыдущих задач, а затем выполняется в одиночку (очередь временно становится serial).
  3. Задачи, поставленные после барьера, ждут его завершения, а затем снова выполняются параллельно.

Пример использования для потокобезопасного кэша:

class ThreadSafeCache<Key: Hashable, Value> {
    private var cache: [Key: Value] = [:]
    // Важно: очередь ДОЛЖНА быть concurrent
    private let queue = DispatchQueue(label: "com.app.cacheQueue", attributes: .concurrent)

    func getValue(for key: Key) -> Value? {
        // Множественные чтения могут выполняться параллельно
        return queue.sync { cache[key] }
    }

    func setValue(_ value: Value, for key: Key) {
        // Запись выполняется эксклюзивно через барьер
        queue.async(flags: .barrier) {
            self.cache[key] = value
        }
    }
}

Строгие правила и предупреждения:

  • Только для concurrent очередей: На serial очередях или глобальных очередях (DispatchQueue.global()) барьер ведет себя как обычная задача, не давая гарантий эксклюзивности.
  • Цель — читатели-писатели: Идеальная абстракция для паттерна «Multiple Readers, Single Writer».
  • Асинхронность: Барьерные задачи обычно добавляются асинхронно (async), чтобы не блокировать вызывающий поток.

Итог: Барьер — это мощный инструмент GCD для организации безопасного доступа к общему ресурсу из нескольких потоков на concurrent очереди.