【发布时间】:2021-03-07 09:54:39
【问题描述】:
我研究过 GCD 和线程安全。 在苹果文档中,GCD 是线程安全的,这意味着多个线程可以访问。 而且我了解了线程安全的含义,即当多个线程访问某个对象时总是给出相同的结果。
我认为 Thread-Safe 和 GCD 的 Thread-Safe 的含义是不一样的,因为我测试了下面写的一些情况,总和为 0 到 9999。
当我多次执行以下代码时,“something.n”值不一样。 如果 GCD 是线程安全的,为什么 "something.n" 的值不一样?
我真的很困惑..你能帮帮我吗? 我真的很想掌握线程安全!!!
class Something {
var n = 0
}
class ViewController: UIViewController {
let something = Something()
var concurrentQueue = DispatchQueue(label: "asdf", attributes: .concurrent)
override func viewDidLoad() {
super.viewDidLoad()
let group = DispatchGroup()
for idx in 0..<10000 {
concurrentQueue.async(group: group) {
self.something.n += idx
}
}
group.notify(queue: .main ) {
print(self.something.n)
}
}
}
【问题讨论】:
-
“在苹果文档中 ...” - 如果您应该分享相关文档的链接,并引用相关摘录,我们可能会更好地澄清他们在说什么。
-
完全不相关,但要非常小心大型
for循环,异步调度到某个队列。这是“线程爆炸”的教科书定义,因为 GCD 工作线程的数量非常有限,可能会导致性能欠佳,在某些情况下甚至会出现死锁。我确定上面的代码 sn-p 只是为了说明目的,但总的来说,要避免线程爆炸。例如。 gist.github.com/robertmryan/fb65510f42e315f24859cd5a24efae4f -
developer.apple.com/library/archive/documentation/General/… 在页面底部,“调度队列本身是线程安全的。换句话说,您可以从系统上的任何线程向调度队列提交任务,而无需先获取锁或同步访问队列。”
-
哦,你真好。我真的很感激你。谢谢!!是的,我只需要检查目的。哦,谢谢你给 concurrentPerfom()。
-
啊,我现在理解混乱了。他们只是说,当您使用调度队列时,您可以从任何您想要的线程安全地使用它们(这是 100% 正确的)。但这并不意味着您使用 GCD 编写的代码本质上是线程安全的!如果你想编写线程安全的代码,你必须自己让它成为线程安全的。他们只是说队列本身可以安全地从您想要的任何线程中使用。
标签: swift thread-safety grand-central-dispatch