Как в одной очереди DispatchQueue выполнять операции параллельно?

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

Ответ

По умолчанию DispatchQueue — серийная (serial). Для параллельного выполнения операций в одной очереди необходимо:

  1. Создать concurrent очередь, указав атрибут .concurrent.
  2. Использовать DispatchQueue.concurrentPerform для итеративного параллельного выполнения или отправлять задачи асинхронно.

Пример:

let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)

// Вариант 1: concurrentPerform
concurrentQueue.async {
    DispatchQueue.concurrentPerform(iterations: 5) { iteration in
        print("Parallel task (iteration)")
    }
}

// Вариант 2: Множество async-задач
for i in 0..<5 {
    concurrentQueue.async {
        print("Async task (i)")
    }
}

Важно: При параллельном доступе к общим ресурсам требуется синхронизация. Используйте:

  • DispatchSemaphore для контроля доступа.
  • Барьеры (DispatchWorkItemFlags.barrier) для эксклюзивного выполнения записи в concurrent очереди.
  • NSLock или os_unfair_lock для низкоуровневой синхронизации.

Альтернатива: OperationQueue с настройкой maxConcurrentOperationCount для более высокоуровневого управления зависимостями и отменой операций.