Выполнение асинхронных задач - PullRequest
0 голосов
/ 07 февраля 2019

Мне нужна помощь, чтобы лучше понять, как работает параллелизм в Swift.

У меня есть код:

DispatchQueue.main.async {
    DispatchQueue.main.async {
        print("A")
        DispatchQueue.main.async {
            print("B")
        }
        print("C")
    }
    print("D")
}

Результат: DACB

Я думаю, что «D» был первым только по одной причине, выполнение первого блока Dispatch состоит из 2 шагов:

  1. Поместить задачу в очередь
  2. Выполнить задачу

И это занимает больше времени, чем выполнение print ("D") .Это верно?

Когда я экспериментировал с очередями параллелизма, в одном из случаев я получил следующий результат: ADCB .

Почему это произошло?

Код очереди параллелизма:

DispatchQueue.global(qos: .utility).async {
    DispatchQueue.global(qos: .utility).async {
        print("A")
        DispatchQueue.global(qos: .utility).async {
            print("B")
        }
        print("C")
    }
    print("D")
}

1 Ответ

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

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

Ваш первый пример предсказуем - он всегда будет вести себя одинаково,потому что вы всегда отправляете задачи в одну и ту же очередь - главную.Задачи, переданные с помощью async, будут выполняться асинхронно (что означает, что функция async будет немедленно возвращена), но новая задача не начнет выполнение, пока не завершится текущая задача.Вот упрощенная модель того, что происходит:

Task 1:
    Submit task 2
    Print "D"

Task 2:
    Print "A"
    Submit task 3
    Print "C"

Task 3:
    Print "B"

Task 1 состоит из отправки Task 2 и материалов для печати.Task 1 выполняется в главной очереди, и Task 2 добавляется в ту же очередь.Это означает, что Task 2 не может запуститься, пока текущее задание - Task 1 - не завершит выполнение.

Пример Seconf немного отличается.Каждый раз, когда вы звоните DispatchQueue.global, вы гарантированно получаете очередь с определенным QoS, но это не обязательно будет та же самая очередь.Может показаться, что в очереди, которую вы отправили print("A"), не было никаких других ожидающих выполнения задач, и она смогла выполнить свою работу немедленно, до возврата метода async.

Использование ранее предоставленной модели - если Task 2 добавлено в очередь, отличную от запущенной Task 1, тогда не нужно ждать, пока Task 1 завершит выполнение.Но опять же, в этом случае все зависит от того, какую очередь вы получаете при каждом вызове DispatchQueue.global, и это не гарантируется

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...