我有多个后台线程,这些线程会不时更新UI。我需要从UI线程中正确终止它们,并确保没有死锁/争用条件。
下面是创建100个操作然后终止它们的示例:
class CancellationToken {
private let updateLock = DispatchSemaphore(value: 1)
private var canceled = false
var isCanceled: Bool {
updateLock.wait()
defer { updateLock.signal() }
return canceled
}
func cancel() {
updateLock.wait()
defer { updateLock.signal() }
canceled = true
}
}
// UI thread
let processingQueue = OperationQueue()
let cancelationToken = CancelationToken()
for _ in 0..100 {
processingQueue.addOperation {
// do some stuff on background thread
...
# 2
guard !cancelationToken.isCanceled else { return }
# 3
DispatchQueue.main.async {
# 4
guard !cancelationToken.isCanceled else { return }
// update UI
}
}
}
// we are still on UI thread
cancelationToken.cancel()
for operation in processingQueue.operations {
operation.waitUntilFinished() #1
}
#2 -> #1 -> #3 -> deadlock
可能在那吗?