При написании инструмента командной строки (CLT) в Swift я хочу обработать много данных. Я решил, что мой код связан с процессором, и производительность может выиграть от использования нескольких ядер. Поэтому я хочу распараллелить части кода. Скажем, я хочу, чтобы достичь следующего псевдокода:Несколько работников в инструменте командной строки Swift
Fetch items from database
Divide items in X chunks
Process chunks in parallel
Wait for chunks to finish
Do some other processing (single-thread)
Теперь я использую НОД и наивный подход будет выглядеть следующим образом:
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)
Однако НОД требует цикла выполнения, так код будет зависать, поскольку группа никогда не выполняется. Runloop можно запустить с dispatch_main()
, но он никогда не выходит. Также можно запустить NSRunLoop
всего несколько секунд, однако это не похоже на твердое решение. Независимо от GCD, как это можно достичь с помощью Swift?
GCD не требует цикла запуска, но ваш код может отправлять блоки в основной поток, и в этом случае вам нужно либо вызвать 'dispatch_main', либо использовать цикл выполнения. – CouchDeveloper
@CouchDeveloper без цикла запуска блоки, представленные в основной поток, не будут работать правильно? Для этого требуется цикл выполнения, даже 'dispatch_main' также создает цикл запуска под капотом. – bouke
'dispatch_main' необязательно создавать цикл запуска. Я действительно верю, что этого не произойдет. Это один из подходов к выполнению блоков, отправленных в основную очередь. И да, он никогда не возвращается, что, вероятно, не имеет большого значения во многих приложениях. Однако я считаю, что если вы не отправляете блоки в основной поток, приложение должно работать нормально без dispatch_main и без цикла запуска (используйте dispatch_groups, чтобы дождаться завершения). – CouchDeveloper