Ответ
Атомарная операция — это неделимая операция над общим ресурсом (например, переменной), которая с точки зрения других потоков выполняется как единое целое. Она либо уже завершена, либо ещё не началась, что гарантирует отсутствие состояния гонки (race condition) при её выполнении.
Зачем это нужно? Простые операции вроде counter += 1 на уровне процессора состоят из нескольких инструкций (чтение-изменение-запись). Без синхронизации два потока могут прочитать старое значение, увеличить его и записать, что приведёт к потере одного увеличения.
Способы обеспечения атомарности в Swift:
-
Использование последовательной очереди (Serial DispatchQueue): Классический подход.
let serialQueue = DispatchQueue(label: "atomic.counter.queue") private var _counter = 0 var counter: Int { get { return serialQueue.sync { _counter } } set { serialQueue.sync { _counter = newValue } } } // Атомарное увеличение func increment() { serialQueue.sync { _counter += 1 } } -
Использование барьеров в concurrent очереди: Для эффективного чтения.
let concurrentQueue = DispatchQueue(label: "cache.queue", attributes: .concurrent) private var cache: [String: Data] = [:] func getData(for key: String) -> Data? { concurrentQueue.sync { cache[key] } // Множественное чтение параллельно } func setData(_ data: Data, for key: String) { concurrentQueue.async(flags: .barrier) { // Запись эксклюзивно cache[key] = data } } -
Пакет Swift Atomics: Низкоуровневая и производительная библиотека.
import Atomics let atomicCounter = ManagedAtomic<Int>(0) atomicCounter.wrappingIncrement(ordering: .relaxed) // Атомарное увеличение
Ключевой принцип: Атомарность гарантирует целостность данных в условиях конкурентного доступа, но не обязательно решает все проблемы синхронизации (например, deadlock).