Swift4.2 не поддерживает stdatomic — что такое простая реализация атомарного логического значения?

#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.