Ios Xcode线程清理器检测数据竞争时出现意外行为
下面是一个代码片段(来自关于GCD的Aubrey Kate课程),它将使Ios Xcode线程清理器检测数据竞争时出现意外行为,ios,swift,xcode,multithreading,data-race,Ios,Swift,Xcode,Multithreading,Data Race,下面是一个代码片段(来自关于GCD的Aubrey Kate课程),它将使Xcode线程消毒剂(又称TSan)-检测数据竞争: import UIKit final class MainViewController: UIViewController { var counter = 0 override func viewDidLoad() { super.viewDidLoad() let queue = DispatchQueue(label: &qu
Xcode
线程消毒剂
(又称TSan)-检测数据竞争
:
import UIKit
final class MainViewController: UIViewController {
var counter = 0
override func viewDidLoad() {
super.viewDidLoad()
let queue = DispatchQueue(label: "q")
queue.async {
for _ in 1 ... 10000 {
Thread.sleep(forTimeInterval: 0.1)
self.counter += 1
}
}
DispatchQueue.main.async {
for _ in 1 ... 10000 {
self.counter += 1
}
}
}
}
但是如果我注释掉线程.sleep(forTimeInterval:0.1)
,TSan
与我无关,不会使程序崩溃
我的问题是什么本质上改变了TSan无法检测到数据竞争???为什么TSan需要
线程.sleep
函数来定位数据竞争
,如果没有它,它就无法定位。今天处理器的速度足够快,可以在下一个异步开始之前完成第一个周期,所以在计数器
上没有竞争,但是当添加sleep
时,会使它们重叠,消毒剂检测到了这一点。您所做的不正确-计数器应同步,-更糟的情况,或在一个队列上更新,-正确的情况。请参阅中的“扩展发生在arc之前”部分。特别是:“在pure before模式中,ThreadSanitizer的行为会有所不同:如果比赛是真实的,比赛可能会被报告,也可能不会被报告(取决于时间,这就是为什么pure before模式不太可预测的原因);如果没有比赛,工具将保持沉默。”@Asperi我正在研究数据比赛的性质。解决它们不是目的。反之亦然