Pull to refresh

Comments 13

А точно код становится многопоточным , в Swift асинхронность = многопоточность?

Беглый гуглеж показал, что, конечно же, под async/await и в Swift подразумевается именно асинхронность.

Типичная ошибка начинающего (и не только, к сожалению) программиста, путающего асинхронность и многопоточность.

Асинхронность и многопоточность в swift - разные понятия. Говоря про async/await - то функции выполняются асинхронно. Но в это же время асинхронная функция может быть выполнена как в одном потоке, так и многопоточно (в зависимости от реализации и контекста)

Из вашей статьи кажется, что async/await это многопоточность

Поправил в некоторых моментах термины "многопоточность" на "асинхронность". Действительно это наверное могло запутать читателей.

Спасибо за замечание

Гораздо интереснее было бы рассмотреть, чем он хуже GCD, так как про лучшесть и так из каждой трубы слышно.

  • Приоритет тасок теперь важен, так как исполняются они не в FIFO, как в GCD. Это может сбить с толку кучу народу, кто всю жизнь писал под GCD/Combine и не трогал треды. Apple на этой важнейшей детали вообще не заострил внимание

  • Акторы обманчиво похожи на обычный джавный монитор на самом объекте (или, если вы из мира ios, на serial queue по заходу в метод), но на самом деле критическая секция длится лишь до suspend'а. На деле это значит, то любые isolated-методы у акторов надо делать с пониманием, что зайти в метод может много клиентов сразу, но исполняется только один за раз. Это, опять же, контринтуитивно и упоминается Apple лишь вскользь

  • Таски захватывают свой контекст сильно до конца исполнения, даже если написать [weak self]. В интернете об этом знают полторы статьи - в итоге память течет нещадно (но, к счастью, утечки чаще всего временные). Опять же, контринтуитивно и в разрез с устоявшимся синтаксисом остального языка

  • Чтобы таски тестировать в юнит тестах, их приходится открывать как private(set), так как свои Executor эппл писать не разрешила. В итоге из каждого объекта торчит лишняя переменная, а тесты ходят по другим потокам даже для возвращения мок-данных, так как нельзя заставить все идти серийно, синхронно на один тред (как с GCD делалось через собственную абстракцию над DispatchQueue).

Добавлю еще один пункт к списку:

  • Если мы работаем с большим количеством потокоблокирующих тасок, то GCD будет отрабатывать такие случаи быстрее чем async/await. Например, если в async варианте функции из примера про Thread Explosion заменить Task.sleep на просто блокирующий sleep, то GCD вариант выполнится быстрее. Это происходит из-за того что в Cooperative Thread Pull выделяется ограниченное кол-во потоков, и при блокировке они быстро заканчиваются.

Вот бы это все, да еще подробно и с примерами :)

Спасибо за статью. В тексте ниже наверное опечатка и имелось в виду «Все наши очереди последовательные (serial)». А то формулировка «асинхронные» вводит в заблуждение.

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

Привык называть GCD'шные очереди синхронными и асинхронными, хотя правильней говорить последовательные и конкуррентные (перевод concurrent как "параллельная" смущает, тк это тоже иной термин)

Поправил этот момент, спасибо за замечание

Новая модель работы с многопоточкой async/await абстрагирует разработчика от понятий потоков и очередей. Новая модель включает в себя Cooperative Thread Pull, который инкапсулирует всю логику по работе с потоками и очередями.

Cooperative Thread Pool, паттерн такой https://en.wikipedia.org/wiki/Thread_pool

Почему в примере с try/catch не показана обработка ошибок в сравнении с вариантом на лямбда функциях?

Насколько я понял вы говорите про функцию ниже (поправьте если я не так понял)

func loadAndProcessImage(from url: URL) async throws -> UIImage {
  let image = try await loadImage(from: url)
  let blurredImage = try await applyBlurFilter(to: image)
  try await cacheToDisk(blurredImage)
  return blurredImage
}

Тут нет обработки ошибок с помощью catch, так как подразумевается что обработка будет происходить в месте вызова данной функции (она сама по себе throws)

Sign up to leave a comment.

Articles