опрос проверяет понимание проблем гонок данных и способов защиты общего состояния.
Потокобезопасность достигается синхронизацией доступа к массиву. Для этого используют serial queue, barrier или блокировки. Нельзя одновременно изменять массив из разных потоков без защиты. Самый простой способ — выполнять все изменения через одну очередь.
Массивы в Swift не являются потокобезопасными. Если несколько потоков одновременно изменяют один массив, возникает гонка данных.
Обычно создается отдельная очередь, отвечающая за доступ к данным:
let syncQueue = DispatchQueue(label: "sync.queue")
var results: [Int] = []
Добавление выполняется так:
syncQueue.async {
results.append(1)
}
При concurrent-очереди можно применять barrier:
let queue = DispatchQueue(label: "queue", attributes: .concurrent)
queue.async(flags: .barrier) {
results.append(1)
}
Также используются:
NSLock
DispatchSemaphore
actor в Swift Concurrency
Самый читаемый и безопасный способ — сериализовать доступ к общему массиву через отдельную очередь.