#swift4.2 #stdatomic
#swift4.2 #stdatomic
Вопрос:
Я часто использую stdatomic в файлах ObjectiveC, но он еще не появился (появится ли когда-нибудь?) в Swift. Я нашел несколько фреймворков с открытым исходным кодом, которые, похоже, предлагают ту же функциональность, но мне нужно что-то маленькое и простое.
Ответ №1:
Я обнаружил следующий код, который хорошо работает для меня:
struct AtomicBoolean {
private var semaphore = DispatchSemaphore(value: 1)
private var b: Bool
var val: Bool {
get {
semaphore.wait()
let tmp = b
semaphore.signal()
return tmp
}
set {
semaphore.wait()
b = newValue
semaphore.signal()
}
}
init(_ initialState: Bool) {
b = initialState
}
}
Он, несомненно, маленький и эффективный! Диспетчерские семафоры также эффективны, они переходят в пространство ядра только в случае конфликта (справочное руководство по программированию параллелизма).
var foo = AtomicBoolean(false)
foo.var = true
if foo.var == true {
print("See!")
}
Комментарии:
1. Особенно, если все, что вам нужно, это атомарное чистое чтение / атомарная чистая запись (не проверка и набор или обмен сравнениями), получение блокировки намного дороже, чем необходимо в случае отсутствия конфликта. При компиляции в asm чтение C
std::atomic<bool>
обходится точно так же дешево, как чтение неатомногоbool
на x86. (Или в слабо упорядоченных ISA,.load(std::memory_ordere_relaxed)
точно так же дешево, как обычныйbool
, но acquire или последовательная согласованность по умолчанию обходятся в инструкцию с барьером загрузки.) И, что важно, между несколькими читателями нет разногласий.2. В любом случае, это работает, чтобы обеспечить потокобезопасность
bool
(с операциями чтения-изменения-записи в качестве функции TODO), но это довольно далеко от эквивалента atomic без блокировки.3. @PeterCordes хотел бы использовать stdatomic в Swift, но даже намека на это не происходит. Часто используйте его в ObjectiveC.