我正在尝试修复代码中的并发竞争条件,我一直在考虑队列。有谁能帮助我理解为什么下面的代码不能在iOS上运行?

class Concurrency {
    private var privateStuff: Int  =  0
    var accessQueue = DispatchQueue(label: "read", qos: DispatchQoS.background, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.workItem, target: nil)
    var writequeue = DispatchQueue(label: "write")
    var stuff: Int {
        get {
            var result: Int!
            accessQueue.sync {
                result = privateStuff
            }
            return result
        }
        set {
            accessQueue.suspend()
            writequeue.sync {
                    privateStuff = newValue
            }
            accessQueue.resume()
        }
    }
}

我仍然有一个竞争条件,所以Xcode说,如果我在这个上面运行大量的reader/writer。
我遗漏了什么吗?谢谢

最佳答案

看起来这个解决方案适合您的问题:
https://medium.com/@oyalhi/dispatch-barriers-in-swift-3-6c4a295215d6
数据竞争条件是由您正在使用两个不同的队列这一事实给出的。当另一个线程请求属性的getter时,没有什么不阻止其他线程在setter中挂起accessQueue
像文章中所描述的链接中有几种方法可以解决这个读者-作者的问题。
我最喜欢的是障碍。
另外,我会对那些队列进行防御,将它们设置为private let而不是vars,以避免一些优秀的同事将mainQueue作为accessQueue传递,从而导致主线程上的线程锁。
所以整件事看起来是这样的:

class Concurrency {
    private var privateStuff: String  =  🖕
    private let queue = DispatchQueue(label: "read-write", qos: DispatchQoS.background, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.workItem, target: nil)
    var stuff: String {
        get {
            var result: String!
            queue.sync {
                result = privateStuff
            }
            return result
        }
        set {
            queue.async(flags: .barrier) {
                    privateStuff = newValue
            }
        }
    }
}

09-11 19:59