Для чего используется барьер (Dispatch Barrier) в GCD?

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

Ответ

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

Типичный use case: реализация thread-safe структуры данных с частыми операциями чтения и редкими операциями записи (паттерн "множество читателей, один писатель").

Пример:

let concurrentQueue = DispatchQueue(label: "com.example.data", attributes: .concurrent)
private var sharedArray = [String]()

// Параллельное чтение (не блокирует другие чтения)
func readAll() -> [String] {
    return concurrentQueue.sync {
        return sharedArray
    }
}

// Эксклюзивная запись (блокирует все другие операции на время выполнения)
func append(_ value: String) {
    concurrentQueue.async(flags: .barrier) {
        sharedArray.append(value)
    }
}

Преимущества перед locks/mutex:

  • Высокая производительность чтения: Множество потоков могут читать данные параллельно.
  • Безопасность записи: Барьер гарантирует, что в момент записи нет конкурентных операций чтения или записи.