【发布时间】:2020-05-27 21:00:50
【问题描述】:
我正在检查使用 GCD 的信号量的正确实现细节,当来自 (https://khanlou.com/2016/04/the-GCD-handbook/) 的一条语句让我感到困惑:“调用 .wait() 将阻塞线程,直到调用 .signal()。这意味着 .signal () 必须从不同的线程调用,因为当前线程完全被阻塞。此外,你不应该从主线程调用 .wait(),只能从后台线程调用。 大多数信号量示例通常从同一个队列调用等待和信号,这似乎也可以正常工作。我在这里遗漏了什么吗?
// Pseudocode from: https://khanlou.com/2016/04/the-GCD-handbook/
// on a background queue
let semaphore = DispatchSemaphore(value: 0)
doSomeExpensiveWorkAsynchronously(completionBlock: {
semaphore.signal()
})
semaphore.wait()
//the expensive asynchronous work is now done
【问题讨论】:
-
大概完成块不会在同一个队列上运行,否则这根本行不通。此外,等待异步工作使其同步。如果你在等待它,它不是异步的。这首先破坏了它异步的全部目的。
-
还有一点值得注意,线程和队列是不同的东西。队列将工作分派到可用线程上,但除了主队列/主线程的情况外,队列和特定线程之间没有绑定。
-
如果您想强制异步任务变为同步,请不要这样做。学习了解异步数据处理的工作原理。
-
基本上,如果您完全使用信号量,那么您做错了。最好考虑现实生活和实际任务,而不是仅仅为了四处碰碰而碰碰边缘情况。
-
不要搞错队列和线程。如果一个队列是并发队列,它可以在多个线程上执行工作项。如果你在一个线程上调用
.wait,并期待未来来自同一个线程的.signal调用,你会很难过(也就是说,永远被阻塞)。另外,不要打电话给.wait。使用完成块等。调度组对于这种情况可能是一个有用的工具。
标签: ios swift multithreading grand-central-dispatch dispatchsemaphore