Ответ
Барьерные задачи (Dispatch barrier) в GCD обеспечивают синхронизацию доступа к общему ресурсу в concurrent очередях.
Преимущества:
- Синхронизация записи при параллельном чтении: Гарантирует, что задача записи выполнится только после завершения всех ранее поставленных задач, а новые задачи начнут выполняться только после барьерной.
- Избегание гонок данных: Полезен для операций модификации shared ресурсов (например, массива или словаря).
- Эффективность: Позволяет сохранить параллельное выполнение задач чтения, блокируя только на время записи.
Недостатки и ограничения:
- Только для custom concurrent очередей: Не работает с глобальными очередями (
DispatchQueue.global()) или serial очередями. - Риск взаимоблокировок (deadlock): При неправильном вложенном использовании (например, sync-барьер в той же очереди).
- Избыточность для простых случаев: Для исключительного доступа к ресурсу проще использовать serial очередь.
Пример использования в Swift:
let concurrentQueue = DispatchQueue(label: "com.example.queue", attributes: .concurrent)
var sharedArray = [String]()
// Параллельные операции чтения
for i in 0..<5 {
concurrentQueue.async {
print("Чтение: (sharedArray)")
}
}
// Барьерная операция записи (выполнится одна, после всех чтений)
concurrentQueue.async(flags: .barrier) {
sharedArray.append("New Item")
print("Запись завершена")
}
// Последующие задачи (начнутся только после барьера)
concurrentQueue.async {
print("После барьера: (sharedArray)")
}