Рубрики
Без рубрики

Одновременные гамбургеры – понимать асинхронность / ждать

Эта статья живет в: Dev.to Medium Github’s Docs’s Docs (включая переводы на другие языки … Tagged с асинхронным, параллелизмом, Python.

Эта статья живет в:

вступление

Современные версии Python (и других языков) имеют поддержку “Асинхронный код” Используя что -то называемое “Coroutines” , с асинхро и ждет синтаксис.

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

Это взято из Документы для FASTAPI , современная структура для строительства API в Python.

Хотя это было написано для Python и Fastapi, вся история и информация актуальна для других языков, которые также имеют Асинхронизация и ждет , как JavaScript и Ржавчина Анкет

Теперь давайте посмотрим эту фразу по частям в разделах ниже:

  • Асинхронный код
  • асинхро а также Ждите
  • Кораки

Асинхронный код

Асинхронный код просто означает, что язык 💬 имеет способ сказать компьютер/программу 🤖, что в какой -то момент в коде он должен будет ждать что -то еще чтобы закончить где -нибудь еще. Допустим, что что -то еще называется «медленным» 📝.

Таким образом, в течение этого времени компьютер может пойти и выполнять какую-то другую работу, а «медленная» заканчивается.

Затем компьютер/программа 🤖 возвращается каждый раз, когда у него есть шанс, потому что он снова ждет, или всякий раз, когда он завершал всю работу, которую он выполнял в этот момент. И он увидит, что какая -либо из задач, которых она ждала, уже закончила, делая все, что должно было сделать.

Затем, для завершения первой задачи требуется первая задача (скажем, наше «медленное» 📝) и продолжает все, что это было связано с этим.

Это «жди чего -то другого» обычно относится к I/O Операции, которые относительно «медленные» (по сравнению со скоростью процессора и памяти оперативной памяти, например, ожидание:

  • Данные от клиента будут отправлены через сеть
  • Данные, отправленные вашей программой, будут получены клиентом через сеть
  • Содержимое файла на диске, которое будет прочитать систему и предоставленную вашей программе
  • Содержание, которое ваша программа дала системе, которая будет написана на диск
  • удаленная операция API
  • операция базы данных для завершения
  • Запрос базы данных для возврата результатов
  • и т.п.

Поскольку время исполнения потребляется в основном в ожидании I/O Операции, они называют их операциями «связанные с вводом/выводом».

Он называется «асинхронным», потому что компьютер/программа не обязательно «синхронизироваться» с медленной задачей, ожидая точного момента, когда задача завершает, не делая ничего, чтобы иметь возможность взять результат задачи и продолжить работу Анкет

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

Для «синхронного» (в отличие от «асинхронного») они обычно также используют термин «последовательный», потому что компьютер/программа выполняет все шаги последовательности перед переходом на другую задачу, даже если эти шаги включают ожидание.

Параллелизм и гамбургеры

Эта идея асинхронно Код, описанный выше, также иногда называется “Согласно параллелизму” Анкет Это отличается от «Параллелизм» Анкет

Параллелизм и Параллелизм Оба относятся к «разным вещам, происходящим более или менее одновременно».

Но детали между параллелизм и Параллелизм совершенно разные.

Чтобы увидеть разницу, представьте себе следующую историю о гамбургерах:

Одновременные гамбургеры

Вы идете со своей влюбленностью, чтобы получить фаст -фуд 🍔, вы стоите в очереди, в то время как кассир 💁 берет заказы у людей перед вами.

Тогда ваша очередь, вы размещаете свой заказ из 2 очень модных гамбургеров 🍔 для вашей влюбленности и вас.

Вы платите 💸.

Кассир 💁 что -то говорит парню на кухне 👨‍ 🍳 Поэтому он знает, что должен подготовить ваши гамбургеры 🍔 (хотя он в настоящее время готовит их к предыдущим клиентам).

Кассир 💁 дает вам номер вашей очереди.

Пока вы ждете, вы идете со своей влюбленностью и выбираете стол, вы сидите и говорите со своей влюбленностью в течение долгого времени (так как ваши гамбургеры очень причудливы и уделите некоторое время, чтобы подготовиться ✨🍔✨).

Когда вы сидите на столе со своей влюбленностью 😍, пока вы ждете гамбургеров 🍔, вы можете потратить это время, восхищаясь тем, насколько классной, милой и умной является ваша влюбленность ✨😍✨.

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

Затем в какой -то момент это наконец -то ваша очередь. Вы идете к стойке, получаете свои гамбургеры 🍔 и возвращаетесь к столу.

Вы и ваша влюбленность 😍 есть гамбургеры 🍔 и хорошо провести время ✨.

Представьте, что вы компьютер/программа 🤖 В этой истории.

Пока вы находитесь на линии, вы просто простаиваете 😴, ожидая своей очереди, не делая ничего очень «продуктивного». Но линия быстрая, потому что кассир 💁 принимает только заказы (не готовит их), так что это нормально.

Затем, когда наступит ваша очередь, вы выполняете фактическую «продуктивную» работу 🤓, вы обрабатываете меню, решаете, что вы хотите, получаете свой выбор, заплатите 💸, проверьте, что вы даете правильный счет или карту, проверьте, что вас взимаете правильно, проверьте, что заказ имеет правильные элементы и т. Д.

Но тогда, даже если у вас все еще нет ваших гамбургеров 🍔 🍔 🍔 🍔, ваша работа с кассиром 💁 «на паузе», потому что вам нужно ждать 🕙, чтобы ваши гамбургеры были готовы.

But as you go away from the counter and sit on the table with a number for your turn, you can switch 🔀 your attention to your crush 😍, and “work” ⏯ 🤓 on that. Тогда вы снова делаете что -то очень «продуктивное» 🤓 🤓, как и флиртование с вашей влюбленностью.

Тогда кассир 💁 говорит: «Я закончил делать гамбургеры» 🍔 🍔, поместив свой номер на дисплее прилавка, но вы не сразу же сразу же прыгаете, когда отображаемый номер изменяется на ваш ход. Вы знаете, что никто не украдет ваши гамбургеры 🍔, потому что у вас есть количество вашей очереди, и у них есть их.

Таким образом, вы ждете, пока ваша влюбленность закончит историю (завершить текущую работу ⏯/задача, которая обрабатывается 🤓), мягко улыбнитесь и скажите, что вы собираетесь за гамбургеры.

Затем вы идете к счетчику 🔀, к первоначальной задаче, которая теперь завершена, выберите гамбургеры 🍔, скажите спасибо и возьмите их к столу. Это завершает этот шаг/задача взаимодействия с счетчиком ⏹. Это, в свою очередь, создает новую задачу «eating Burgers» ⏯ ⏯, но предыдущий из «получения гамбургеров» завершена ⏹.

Параллельные гамбургеры

Теперь давайте представим, что это не «одновременные гамбургеры», а «параллельные гамбургеры».

Вы идете со своей влюбленностью, чтобы получить параллельный фаст -фуд 🍔.

Вы стоите в очереди, в то время как несколько (скажем, 8) кассиров, которые в то же время являются поварами 👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳 Возьмите заказы у людей перед вами.

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

Затем, наконец, ваша очередь, вы размещаете свой заказ из 2 очень модных гамбургеров 🍔 для вашей влюбленности и вас.

Вы платите 💸.

Кассир идет на кухню 👨‍🍳.

Вы ждете, стоя перед стойкой 🕙, так что никто другой не берет ваши гамбургеры 🍔, прежде чем вы это сделаете, так как нет цифр для поворотов.

Поскольку вы и ваша влюбленность заняты, не позволяя никому оказаться перед вами и не принимать свои гамбургеры, когда они прибывают 🕙, вы не можете обратить внимание на свою влюбленность ».

Это «синхронная» работа, вы «синхронизированы» с кассиром/поваром 👨‍🍳. Вы должны подождать 🕙 и быть там в тот момент, когда кассир/повар заканчивает гамбургеры 🍔 и дает их вам, или иным образом, кто -то другой может их взять.

Затем ваш кассир/повар 👨‍🍳, наконец, возвращается с вашими гамбургерами 🍔, после долгого ожидания 🕙 перед прилавками.

Вы берете свои гамбургеры 🍔 и идете к столу со своей влюбленностью 😍.

Вы просто едите их, и вы закончили 🍔 ⏹.

Не было много разговоров или флирта, так как большую часть времени было потрачено на ожидание 🕙 перед стойкой 😞.

В этом сценарии параллельных гамбургеров вы являетесь компьютером/программой 🤖 с двумя процессорами (вы и ваша влюбленность), оба ожидая 🕙 и уделяете их вниманию ⏯, чтобы «ждать на прилавке» 🕙 надолго.

В магазине быстрого питания есть 8 процессоров (кассиры/повара) 👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳. В то время как в одновременном магазине гамбургеров могло быть всего 2 (один кассир и один повар) 💁 👨‍🍳 👨‍🍳 👨‍🍳 👨‍🍳 👨‍🍳 👨‍🍳 👨‍🍳 👨‍🍳 👨‍🍳 👨‍🍳

Но, тем не менее, последний опыт не самый лучший 😞.

Это была бы параллельная эквивалентная история для гамбургеров 🍔.

Для более «реальной жизни» примера этого представьте банк.

В последнее время у большинства банков было несколько кассиров 👨‍💼👨‍💼👨‍💼👨‍💼 и большая линия 🕙🕙🕙🕙🕙🕙🕙🕙.

Все кассиры выполняют всю работу с одним клиентом после другого 👨‍💼⏯.

И вы должны ждать 🕙 в течение долгого времени или вы теряете свою очередь.

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

Вывод гамбургера

В этом сценарии «Бургеров быстрого питания с вашей влюбленностью», так как есть много ожидания 🕙, имеет гораздо больше смысла иметь одновременную систему ⏸🔀⏯.

Это относится к большинству веб -приложений.

Многие, многие пользователи, но ваш сервер ждет 🕙 для их не очень хорошего соединения, чтобы отправить их запросы.

А потом ждем 🕙 снова, чтобы ответы вернулись.

Это «ожидание» 🕙 измеряется в микросекундах, но все же, суммируя все это, в конце концов, это много ожидания.

Вот почему имеет большой смысл использовать асинхронный ⏸🔀⏯ код для веб -API.

Большинство существующих популярных рамок Python (включая Flask и Django) были созданы до того, как существовали новые асинхронные особенности в Python. Таким образом, способы, которыми они могут быть развернуты параллельным выполнением поддержки, и более старую форму асинхронного выполнения, которая не так мощна, как новые возможности.

Несмотря на то, что в Django была разработана основная спецификация для асинхронного веб -питона (ASGI), чтобы добавить поддержку веб -кокеты.

Такая асинхронность – это то, что делало Nodejs популярными (хотя Nodejs не параллельно), и это сила Go как языка программирования.

И это тот же уровень производительности, который вы получаете с FASTAPI Анкет

И, поскольку вы можете иметь параллелизм и асинхронность одновременно, вы получаете более высокую производительность, чем большинство тестируемых рамок Nodejs, и наравне с GO, который является составленным языком, ближе к C (Все спасибо Starlette) .

Параллелизм лучше ли параллелизм?

Неа! Это не мораль истории.

Параллелизм отличается от параллелизма. И это лучше на конкретный Сценарии, которые включают в себя много ожидания. Из -за этого это, как правило, намного лучше, чем параллелизм для разработки веб -приложений. Но не для всего.

Итак, чтобы сбалансировать это, представьте себе следующий рассказ:

Вы должны почистить большой грязный дом.

Да, это вся история Анкет

Там нет никакого ожидания 🕙 где бы то ни было, просто много работы, в нескольких местах дома.

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

Чтобы закончить или без поворотов (параллелизм) потребуется столько времени, и вы бы проделали столько же работы.

Но в этом случае, если бы вы могли принести 8 бывших каштаных/поваров/теперь чистотеров 👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳, и каждый из них (плюс вы) могли взять зону дома, чтобы очистить его, вы можете выполнить всю работу в параллель , с дополнительной помощью, и закончить гораздо раньше.

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

И поскольку большая часть времени выполнения принимается по фактической работе (вместо ожидания), а работа на компьютере выполняется Процессор , они называют эти проблемы «связанным с процессором».

Общие примеры операций, связанных с границей ЦП, – это вещи, которые требуют сложной математической обработки.

Например:

  • Аудио или Обработка изображений Анкет
  • Компьютерное зрение : изображение состоит из миллионов пикселей, каждый пиксель имеет 3 значения/цвета, обработка, которая обычно требует вычисления чего -либо на этих пикселях, все это одновременно.
  • Машинное обучение : Обычно требуется много умножений «матрицы» и «вектора». Подумайте об огромной электронной таблице с числами и умножением их всех вместе.
  • Глубокое обучение : Это подполе машинного обучения, так что применимо. Просто не существует ни одной электронной таблицы чисел для умножения, но огромный набор из них, и во многих случаях вы используете специальный процессор для создания и/или использования этих моделей.

Параллелизм + параллелизм: веб -сайт + машинное обучение

С FASTAPI Вы можете воспользоваться преимуществами параллелизма, который очень распространен для веб -разработки (то же самое основное привлекательное из Nodejs).

Но вы также можете использовать преимущества параллелизма и многопроцессы (имея несколько процессов, работающих параллельно) для ЦП связан Рабочие нагрузки, как и в системах машинного обучения.

Это, плюс простой факт, что Python является основным языком для Наука данных Машинное обучение и особенно глубокое обучение, делают FastAPI очень хорошим совпадением для веб -API и приложений и приложений машинного обучения в области данных/машинного обучения (среди многих других).

Чтобы увидеть, как достичь этого параллелизма в производстве, см. Docs Fastapi для развертывания Анкет

асинхронно и ждет

Современные версии Python имеют очень интуитивно понятный способ определения асинхронного кода. Это делает его похожим на обычный «последовательный» код и делает «ожидание» для вас в нужные моменты.

Когда есть операция, которая потребует ожидания, прежде чем предоставить результаты, и будет поддержать эти новые функции Python, вы можете кодировать ее как:

burgers = await get_burgers(2)

Ключ здесь – Ждите . Он говорит Python, что должен ждать ⏸ для get_burgers (2) Чтобы закончить делать свое дело, прежде чем хранить результаты в Бургеры Анкет With that, Python will know that it can go and do something else 🔀 ⏯ in the meanwhile (like receiving another request).

Для ждет Чтобы работать, это должно быть внутри функции, которая поддерживает эту асинхронность. Для этого вы просто объявите это асинхромат def :

async def get_burgers(number: int):
    # Do some asynchronous stuff to create the burgers
    return burgers

… вместо def :

# This is not asynchronous
def get_sequential_burgers(number: int):
    # Do some sequential stuff to create the burgers
    return burgers

С асинхромат def , Python знает, что внутри этой функции он должен знать о ждет выражения, и что он может «приостановить» ⏸ выполнение этой функции и пойти что -нибудь еще 🔀, прежде чем вернуться.

Когда вы хотите позвонить асинхромат def Функция, вы должны «ждать» этого. Так что это не сработает:

# This won't work, because get_burgers was defined with: async def
burgers = get_burgers(2)

Другие формы асинхронного кода

Этот стиль использования Асинхронизация и ждет относительно новый на языке.

Но это делает работу с асинхронным кодом намного проще.

Этот же синтаксис (или почти идентичный) был также включен недавно в современные версии JavaScript (в браузере и Nodejs).

Но до этого обработка асинхронного кода была довольно сложной и трудной.

В предыдущих версиях Python вы могли бы использовать потоки или Gevent Анкет Но код гораздо сложнее понять, отлаживать и думать.

В предыдущих версиях Nodejs/Browser JavaScript вы бы использовали «обратные вызовы». Что приводит к обратный вызовой ад .

Кораки

Coroutine это просто очень причудливый термин для вещи, возвращенной асинхромат def функция Python знает, что это что -то вроде функции, которую он может начать, и что в какой -то момент она закончится, но она также может быть приостановлена ⏸ внутри, всякий раз, когда есть Ждите внутри.

Но вся эта функциональность использования асинхронного кода с Асинхронизация и ждет много раз обобщено как использование «Coroutines». Это сопоставимо с основной ключевой особенностью GO, «Goroutines».

Вывод

Давайте посмотрим ту же фразу сверху:

Современные версии Python имеют поддержку “Асинхронный код” Используя что -то называемое “Coroutines” , с асинхро и ждет синтаксис.

Это должно иметь больше смысла сейчас. ✨

Все это то, что способствует Fastapi (через Starlette) и что делает его такими впечатляющими результатами.

Учить больше

В этой версии есть некоторые детали, которые очень специфичны для Fastapi. Если вы хотите изучить их, в том числе как получить асинхронные преимущества производительности, в то же время писать стандарт def функции и использование стандартных библиотек, проверьте Fastapi Docs Анкет

Если вы хотите более глубокого и гораздо более технического объяснения всего этого, проверьте это Видеоспись от EdgedB по Lłukasz Langa Анкет

Обо мне

Привет! 👋 Я Себастьян Рамирес ( tiangolo ).

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

Оригинал: “https://dev.to/tiangolo/concurrent-burgers-understand-async-await-3n20”