对于SWIFT中的读者-写入者问题,我似乎有一个classic 的解决方案:使用具有写障碍的并发DispatchQueue.然而,当我运行测试代码时,它死机了.
下面是我想成为线程安全的数据 struct :
class Container<T> {
private var _value: T
private let _queue = DispatchQueue(label: "containerQueue", attributes: .concurrent)
init(_ value: T) {
self._value = value
}
var value: T {
get {
_queue.sync {
_value
}
}
set {
_queue.async(flags: .barrier) {
self._value = newValue
}
}
}
}
下面是我的测试代码:
class ContainerTest {
let testQueue = DispatchQueue(label: "testQueue", attributes: .concurrent)
var container = Container(0)
let group = DispatchGroup()
func runTest() {
for i in 0..<1000 {
testQueue.async(group: group) {
self.container.value = max(i, self.container.value)
}
}
group.notify(queue: .main) {
print("Finished")
}
}
}
重复运行的代码片段只是一些随机的读写操作.它并没有试图产生任何合理的东西,它只是在那里对数据 struct 进行压力测试.
因此,当我运行此命令时,不会打印"完成".但是,如果我将_queue.async(flags: .barrier)
更改为_queue.sync(flags: .barrier)
,那么我会看到"Finish"打印出来.
我猜,当我使用async
写入版本时,我会遇到死锁,但为什么呢?这是通常使用的教科书读者-作者解决方案.也许是我的测试代码有问题,但是,为什么呢?