Многопоточность для петель в Свифт 4 - PullRequest
0 голосов
/ 22 февраля 2019

Мне нужна небольшая помощь по правильной многопоточности цикла for для swift 4. Должен ли я использовать обычную очередь отправки или использовать параллельную многопоточность?Или я думаю об этом неправильно?Конкретный пример, который я рассматриваю здесь: скажем, мы хотим сделать что-то со списком объектов, например, получить изображение пользователя из базы данных для всех пользователей, у которых его нет в локальной базе данных на устройстве.

let utilityQueue = DispatchQueue(label: "com.company.utility", qos: .utility)
for i in 1 ... 10000 {
    utilityQueue.async {
        getMissingImage(user[i])
    }
}

Вышеприведенное, кажется, работает для меня, но я нашел другой вариант в моем чтении, но с использованием параллелизма, например ниже

let concurrentQueue = DispatchQueue(label: "com.company.concurrent", attribute: .concurrent)
for i in 1 ... 10000 {
    concurrentQueue.async {
        getMissingImage(user[i])
    }
}

Что является правильным или есть лучший способсправиться с этим, что мне не хватает?

1 Ответ

0 голосов
/ 22 февраля 2019

Попытка запустить неограниченное количество одновременных задач опасна, поскольку в GCD очень ограниченное количество рабочих потоков, и если вы их исчерпаете, вы можете отрицательно повлиять на другие операции в приложении.

Итакрассмотрим ваш пример:

let concurrentQueue = DispatchQueue(label: "com.company.concurrent", attributes: .concurrent)
for i in 0 ..< 10_000 {
    concurrentQueue.async {
        self.getMissingImage(self.user[i])
    }
}

Вы можете использовать OperationQueue, который позволяет легко ограничивать степень параллелизма, в этом примере не более 4 одновременно:

let queue = OperationQueue()
queue.name = "com.company.concurrent"
queue.qualityOfService = .userInitiated
queue.maxConcurrentOperationCount = 4

for i in 0 ..< 10_000 {
    queue.addOperation {
        self.getMissingImage(self.user[i])
    }
}

Youможет выполнить нечто подобное с семафорами GCD, но это немного более хрупко, и я бы предложил выше.

Обратите внимание, это предполагает, что getMissingImage работает синхронно (то есть не вернется, пока задача не будет полностью выполнена),Если нет, вам придется использовать другие схемы.

...