Ios Xcode线程清理器检测数据竞争时出现意外行为

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

下面是一个代码片段(来自关于GCD的Aubrey Kate课程),它将使
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我正在研究数据比赛的性质。解决它们不是目的。反之亦然