Swift COW螺纹安全

时间:2017-12-13 21:52:59

标签: swift multithreading copy-on-write

我正在寻找copy-on-write如何在swift中工作。而isKnownUniquelyReferenced documentation有点困惑。特别是本节:

  

如果同时由多个线程访问作为对象传递的实例,则此函数仍可返回true。因此,您只能通过适当的线程同步从变异方法调用此函数。这将确保isKnownUniquelyReferenced(_ :)仅在存在一个访问者时才返回true,或者当存在竞争条件时,这已经是未定义的行为。

想象一下案例。

  1. 我们内部没有同步的COW结构。
  2. 拥有此结构的实例并使用锁保护它的类
  3. 此结构的吸气剂
  4. 并希望安全地从此getter线程返回副本
  5. import Foundation
    
    class StorageBuffer {
        var field: Int = 1
    
        init(_ field: Int) {
            self.field = field
        }
    
        func copy() -> StorageBuffer {
            return StorageBuffer(field)
        }
    }
    
    struct Storage {
        private var _buffer = StorageBuffer(1)
    
        var field: Int {
            get {
                return _buffer.field
            }
            set {
                if !isKnownUniquelyReferenced(&_buffer) {
                    _buffer = _buffer.copy()
                }
    
                _buffer.field = newValue
            }
        }
    }
    
    class StorageAware {
        private var _storage = Storage()
        private let _storageGuard = NSLock()
    
        var storage: Storage {
            _storageGuard.lock()
            defer {
                _storageGuard.unlock()
            }
    
            return _storage
        }
    }
    

    由于真正的复制将在以后发生。是否足以同步吸气剂?在这种情况下,它是必要的还是结构本身是线程安全的? 在任何地方都有关于快速线程安全的完整文档吗?

1 个答案:

答案 0 :(得分:1)

CoW结构与Int一样线程安全,即它们不是原子的。因此,就像在修改Int时必须锁定并发访问一样,例如

lock.lock()
var myInt = _storedInt // lock required, not an atomic op
lock.unlock()
myInt += 1

复制 CoW结构时,您必须做同样的事情(尽管标记为_storage的{​​{1}}本身没有被修改,因此,这表明-您需要锁定对var的写访问权限。

但是,当您执行此操作时,_storage保证如果引用是唯一的,则返回true。

错误:

isKnownUniquelyReferenced

右:

var myStorage = _storage // this can race
myStorage.value = 10

错误的版本显示了文档所谈论的种族。