运行TSan工具时,我的代码中出现了竞争条件。由于同一时间已从不同的队列和线程访问了相同的代码,这就是为什么我不能使用串行队列或屏障的原因,因为队列将仅阻止访问共享资源的单个队列,而不会阻止其他队列。
我使用objc_sync_enter(object) | objc_sync_exit(object)
并锁定了NSLock() or NSRecursiveLock()
来保护共享资源,但是它们也无法正常工作。
当我在目标C中使用@synchronized()
关键字来保护共享资源时,它可以按预期运行,并且在特定的代码块中没有竞争条件。
因此,在Swift中保护数据的另一种方法是,我们不能在Swift语言中使用@synchronized()
关键字。
答案 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
的访问是原子和线程安全的,而调用者不必做任何特殊的事情。多个读取器可以同时读取而不会互相阻塞。即使在许多读者面前,作家也不会饿死。