асинхронные задачи в главном потоке совпадают с синхронными задачами? - PullRequest
1 голос
/ 30 марта 2020

Я знаю разницу между этими двумя типами.

Для асинхронных c задач следующая задача будет запущена после начала текущей, что означает, что задачи будут отправлены в несколько потоков, если есть доступные потоки.
Для задач syn c следующая задача будет запущена после завершения текущей.

Как основной поток может выполнять асинхронные c задачи, поскольку он имеет только один поток?

Это сбивает с толку.
Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 30 марта 2020

Ваши определения асинхронного и синхронного не совсем верны.

В Grand Central Dispatch вы рассматриваете очереди , а не потоков . Очередь - это либо очередь последовательной отправки, либо очередь одновременной отправки.

Очередь последовательной отправки может запускать одну задачу за раз, и задачи отправляются одна за другой (последовательно).

A Очередь одновременной отправки может одновременно выполнять несколько задач в нескольких потоках.

Задачи выполняются в потоках, а Grand Central Dispatch заботится о назначении задач для вас.

Основная очередь - это специальная последовательная диспетчеризация. очередь, которая только назначает задачи основному потоку. Другие очереди могут назначать задачи любому доступному потоку, включая основной поток.

Теперь для синхронной и асинхронной диспетчеризации разница состоит в том, блокирует ли диспетчеризация текущий поток до тех пор, пока отправленная задача не будет завершена (синхронно), или поставит в очередь задачу без блокировки текущего потока (асинхронно).

Когда вы отправляете асинхронно в основную очередь, вы предоставляете единицу работы, которую Grand Central Dispatch назначит основному потоку в будущем, но ваш код продолжает выполняться, не дожидаясь завершения этого отправленного элемента.

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

Что вы не может выполнить диспетчеризацию синхронно в основную очередь из основной очереди (или, в более общем случае, синхронную отправку в любую очередь последовательной отправки из этой же очереди), поскольку вы создадите взаимоблокировку ,

Синхронная отправка блокирует текущий поток / очередь до тех пор, пока отправленный элемент не будет завершен. В очереди последовательной отправки отправленный элемент не может быть выполнен, поскольку очередь отправки заблокирована.

1 голос
/ 12 апреля 2020

Для асинхронных задач c следующая задача будет запускаться после начала текущей, что означает, что задачи будут отправляться в несколько потоков, если есть доступные потоки.

Не совсем. Распределение только асинхронно означает, что текущий поток будет не ждать, пока отправленный код не завершится sh. Это не имеет абсолютно никакого отношения к тому, является ли эта очередь назначения последовательной или параллельной.

Для задач syn c следующая задача будет запущена после завершения текущей.

Опять не совсем. Синхронная отправка означает только то, что текущий поток будет ждать, пока отправленный код завершит выполнение sh.

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

Как основной поток может выполнять асинхронные c задачи, поскольку он имеет только один поток?

Как теперь, вероятно, очевидно, «асинхронный» против «синхронный» не является характеристикой c отправляемая задача, а скорее только определяет, должен ли поток, из которого вы отправляете, ждать или нет.

Итак, рассмотрим некоторый код, который асинхронно отправляет код обратно в основной поток:

let task = URLSession.dataTask(with: request) { data, _, _ in
    let results = ...                 // on `URLSession` background serial queue, only populate local variables
    DispatchQueue.main.async {
        self.objects = results        // dispatch model updates back to main queue
        self.tableView.reloadData()   // also update UI from main queue
    }
}
task.resume()

В приведенном выше примере мы отправляем обновления модели и пользовательского интерфейса в основную очередь, потому что мы находимся в фоновой очереди URLSession (которая также является последовательной очередью). И мы отправляем его асинхронно, потому что у последовательной очереди URLSession нет никаких оснований ждать, пока отправленный код не достигнет sh. Мы могли бы отправить его синхронно, но зачем нам блокировать очередь URLSession, даже если только на несколько дополнительных миллисекунд.

...