【发布时间】:2021-12-27 19:01:31
【问题描述】:
在 Swift 中编写命令行工具 (CLT) 时,我想处理大量数据。我已经确定我的代码受 CPU 限制,并且性能可以从使用多个内核中受益。因此,我想并行化部分代码。假设我要实现以下伪代码:
Fetch items from database
Divide items in X chunks
Process chunks in parallel
Wait for chunks to finish
Do some other processing (single-thread)
现在我一直在使用 GCD,一个幼稚的方法看起来像这样:
let group = dispatch_group_create()
let queue = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT)
for chunk in chunks {
dispatch_group_async(group, queue) {
worker(chunk)
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
但是 GCD 需要一个运行循环,因此代码将挂起,因为该组永远不会执行。 runloop 可以用dispatch_main() 启动,但它永远不会退出。也可以在几秒钟内运行NSRunLoop,但这并不是一个可靠的解决方案。不考虑 GCD,用 Swift 怎么实现呢?
【问题讨论】:
-
GCD 不需要运行循环 - 但您的代码可能会向主线程提交块,在这种情况下您需要调用
dispatch_main或使用运行循环。 -
@CouchDeveloper 没有运行循环提交给主线程的块不会运行对吗?因此需要一个运行循环来运行它们,即使
dispatch_main也会在后台创建一个运行循环。 -
dispatch_main不一定需要创建运行循环。其实我相信不会。这是执行提交到主队列的块的一种方法。是的,它永远不会返回,这在许多应用程序中可能不是很有意义。但是,我相信,如果您不向主线程分派块,则应用程序应该可以在没有 dispatch_main 和运行循环的情况下正常运行(使用 dispatch_groups 等待完成)。
标签: swift