迅速避免数据争用情况

时间:2018-08-31 05:47:43

标签: ios swift concurrency

运行TSan工具时,我的代码中出现了竞争条件。由于同一时间已从不同的队列和线程访问了相同的代码,这就是为什么我不能使用串行队列或屏障的原因,因为队列将仅阻止访问共享资源的单个队列,而不会阻止其他队列。

我使用objc_sync_enter(object) | objc_sync_exit(object)并锁定了NSLock() or NSRecursiveLock()来保护共享资源,但是它们也无法正常工作。

当我在目标C中使用@synchronized()关键字来保护共享资源时,它可以按预期运行,并且在特定的代码块中没有竞争条件。

因此,在Swift中保护数据的另一种方法是,我们不能在Swift语言中使用@synchronized()关键字。

PFA屏幕截图以供参考- Data Race

1 个答案:

答案 0 :(得分:4)

我不明白“我不能使用串行队列或屏障,因为队列将仅阻止访问共享资源的单个队列,而不阻止其他队列。”使用带有障碍的并发队列是解决此问题的标准方法。

class MultiAccess {
    private var _property: String = ""
    private let propertyQueue = DispatchQueue(label: "MultiAccess.property")
    var property: String {
        get {
            var result: String!
            propertyQueue.sync {
                result = self._property
            }
            return result
        }
        set {
            propertyQueue.async(flags: .barrier) {
                self._property = newValue
            }
        }
    }
}

通过这种构造,对property的访问是原子和线程安全的,而调用者不必做任何特殊的事情。多个读取器可以同时读取而不会互相阻塞。即使在许多读者面前,作家也不会饿死。