Какие проблемы многопоточности решаются примитивами синхронизации

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

Ответ

Примитивы синхронизации (мьютексы, семафоры, очереди и т.д.) решают несколько ключевых проблем многопоточности:

  1. Race conditions - когда результат зависит от порядка выполнения потоков. Решается блокировкой доступа к общим ресурсам:
let lock = NSLock()
var sharedValue = 0

DispatchQueue.concurrentPerform(iterations: 100) { _ in
    lock.lock()
    sharedValue += 1
    lock.unlock()
}
  1. Deadlocks - взаимоблокировка потоков. Решается правильным порядком захвата блокировок или использованием атомарных операций.

  2. Гонка данных - неконсистентное состояние данных при одновременном чтении/записи. Решается reader-writer блокировками:

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

queue.async(flags: .barrier) {
    // эксклюзивная запись
}

queue.async {
    // параллельное чтение
}
  1. Голодание потоков - когда одни потоки монополизируют ресурс. Решается чередованием доступа (например, семафорами).