【发布时间】:2021-08-30 19:39:11
【问题描述】:
我的意图是了解 Swift 5.5 的 async-await 使用的“协作线程池”,以及任务组如何自动约束并发程度:考虑以下任务组代码,并行进行 32 次计算:
func launchTasks() async {
await withTaskGroup(of: Void.self) { group in
for i in 0 ..< 32 {
group.addTask { [self] in
let value = await doSomething(with: i)
// do something with `value`
}
}
}
}
虽然我希望它会限制并发程度,但正如所宣传的那样,我一次只能获得两个(!)并发任务。这比我预期的要严格得多:
如果我使用旧的 GCD concurrentPerform ...
func launchTasks2() {
DispatchQueue.global().async {
DispatchQueue.concurrentPerform(iterations: 32) { [self] i in
let value = doSomething(with: i)
// do something with `value`
}
}
}
...我一次得到 12 个,充分利用设备(我的 6 核 i9 MacBook Pro 上的 iOS 15 模拟器)同时避免线程爆炸:
(FWIW,这两者都在 Big Sur 上运行的 Xcode 13.0 beta 1 (13A5154h) 中进行了分析。请忽略这两次运行中各个“工作”的细微差别,因为所讨论的功能只是为一个随机的持续时间;关键的观察是并发程度是我们所期望的。)
这个新的 async-await(和任务组)自动限制并行度非常好,但是 async-await 的协作线程池比我预期的要受限制得多。而且我认为无法调整该池的这些参数。我们如何才能更好地利用我们的硬件,同时仍然避免线程爆炸(不求助于非零信号量或操作队列等旧技术)?
【问题讨论】:
标签: ios swift async-await grand-central-dispatch swift5.5