Корутины python что это

Сопрограммы в Python

Генераторы

Любой более-менее приличный программист на Python знает, что есть такая замечательная штука, как функции-генераторы. Главная их особенность — это сохранение состояния между вызовами.

Я подразумеваю что вы знаете как они работают, поэтому просто напомню, как это выглядит.
Возьмём вот такую функцию:

Эта функция принимает на вход имя файла и возвращает его строчка за строчкой, не загружая целиком в память, что может быть необходимо при чтении больших файлов.
Такой приём называют ленивым (lazy) чтением, подразумевая, что мы не делаем «работу» без необходимости.

В общем случае, работа с генераторами выглядит следующим образом:

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

Так же возможна короткая запись генератора:

Похоже на списковые выражения, верно? Только не требует создания всего списка range(0, 100*10000) в памяти, возвращаемое значение «вычисляется» каждый раз при обращении.

Сопрограммы как частный случай генераторов

А теперь о том, ради чего это, собственно, затевалось. Оказывается, генератор может не только возвращать значения, но и принимать их на вход.

О стандарте можно почитать тут PEP 342.

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

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

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

На этом примере можно понять как писать свои более сложные (и полезные) сопрограммы.

Заключение.

Хоть проблемы, которые можно решить этим инструментом затрагивают очень многие области (такие как асинхронное программирование), многие разработчики предпочитают более привычные инструменты ООП. Но при этом сопрограммы могут быть очень полезным инструментом в вашем арсенале, поскольку они достаточно наглядны, а создание фунций более дешёвая операция по сравнению с созданием объекта класса.

Да и определённый академический интерес они представляют, как мне кажется.

Вот такая вот первая статья.

Источник

Асинхронное программирование в Python: краткий обзор

Когда говорят о выполнении программ, то под «асинхронным выполнением» понимают такую ситуацию, когда программа не ждёт завершения некоего процесса, а продолжает работу независимо от него. В качестве примера асинхронного программирования можно привести утилиту, которая, работая асинхронно, делает записи в лог-файл. Хотя такая утилита и может дать сбой (например, из-за нехватки свободного места на диске), в большинстве случаев она будет работать правильно и ей можно будет пользоваться в различных программах. Они смогут её вызывать, передавая ей данные для записи, а после этого смогут продолжать заниматься своими делами.

Корутины python что это. Смотреть фото Корутины python что это. Смотреть картинку Корутины python что это. Картинка про Корутины python что это. Фото Корутины python что это

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

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

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

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

Асинхронное программирование в Python

Изначально в Python для решения задач асинхронного программирования использовались корутины, основанные на генераторах. Потом, в Python 3.4, появился модуль asyncio (иногда его название записывают как async IO ), в котором реализованы механизмы асинхронного программирования. В Python 3.5 появилась конструкция async/await.

Для того чтобы заниматься асинхронной разработкой на Python, нужно разобраться с парой понятий. Это — корутины (coroutine) и задачи (task).

Корутины

Обычно корутина — это асинхронная (async) функция. Корутина может быть и объектом, возвращённым из корутины-функции.

Если при объявлении функции указано то, что она является асинхронной, то вызывать её можно с использованием ключевого слова await :

Такая конструкция означает, что программа будет выполняться до тех пор, пока не встретит await-выражение, после чего вызовет функцию и приостановит своё выполнение до тех пор, пока работа вызванной функции не завершится. После этого возможность запуститься появится и у других корутин.

Задачи

Задачи позволяют запускать корутины в цикле событий. Это упрощает управление выполнением нескольких корутин. Вот пример, в котором используются корутины и задачи. Обратите внимание на то, что сущности, объявленные с помощью конструкции async def — это корутины. Этот пример взят из официальной документации Python.

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

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

Пример

Итоги

Существуют ситуации, в которых использование задач и корутин оказывается весьма полезным Например, если в программе присутствует смесь операций ввода-вывода и вычислений, или если в одной и той же программе выполняются разные вычисления, можно решать эти задачи, запуская код в конкурентном, а не в последовательном режиме. Это способствует сокращению времени, необходимого программе на выполнение определённых действий. Однако это не позволяет, например, выполнять вычисления одновременно. Для организации подобных вычислений применяется мультипроцессинг. Это — отдельная большая тема.

Уважаемые читатели! Как вы пишете асинхронный Python-код?

Источник

Корутины в Python

Когда говорят «написать корутину», обычно подразумевают асинхронную функцию. Корутины можно ставить на паузу, чтобы дать другим функциям немного поработать. В этом заключается принцип асинхронности. О нём мы рассказывали в этой статье.

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

async говорит Питону о том, что мы пишем не просто функцию, а асинхронную функцию. Просто добавили async и всё, функция теперь асинхронная.

await asyncio.sleep(0) — это команда корутине «Дай поработать другим!»

Сразу покажем, как это выглядит на практике:

Когда корутина закончится?

Если мы хотим запустить наш счётчик сначала, придётся создать новую корутину, вызвав count_to_three() :

Обычно заранее не известно сколько await будет до момента «истощения», поэтому исключение приходится «перехватывать»:

Нельзя запускать истощённую корутину.

Добиваемся асинхронности

С корутинами разобрались, останавливать их научились. А зачем.

Корутины позволят вашему коду работать асинхронно, т.е. делать несколько вещей одновременно. Допустим, вы решили скачать несколько файлов. Обычный, синхронный код скачивает файлы по-очереди. Сначала первый файл целиком, затем второй, тоже целиком. Асинхронный код качает файлы одновременно, по кусочкам. Приведём пример скачивания двух файлов:

Разберём как работает код:

Мы положили их в список coroutines

В бесконечном цикле мы по очереди запускаем все корутины из списка. Если вышла ошибка StopIteration — корутина истощилась, т.е. файл скачан. Убираем её из списка, корутина больше запускаться не будет.

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

Передать параметры в асинхронную функцию

В плане аргументов асинхронные функции ничем не отличаются от обычных. Доработаем пример со счетчиком и вместо async def count_to_three напишем универсальную функцию async def count :

Попробуйте бесплатные уроки по Python

Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

Переходите на страницу учебных модулей «Девмана» и выбирайте тему.

Источник

Корутины и задачи¶

В этом разделе приведено высокоуровневое API asyncio для работы с корутинами и задачами.

Корутины¶

Заметим, что простой вызов корутины не приведёт к её выполнению:

Чтобы фактически запустить корутину, asyncio предоставляет три основных механизма:

Функция asyncio.run() для запуска функции точки входа верхнего уровня «main()» (см. приведённый пример выше)

Ожидающая корутина. Следующий фрагмент кода напечатает «hello» после ожидания в 1 секунду, а затем напечатает «world» после ожидания в течении ещё 2х секунд

Давайте изменим приведённый выше пример и запустим две say_after корутины конкурентно:

Обратите внимание, что ожидаемые выходные данные теперь показывают, что фрагмент выполняется на 1 секунду быстрее, чем ранее:

Ожидаемые объекты¶

Мы говорим, что объект является ожидаемым объектом, если его можно использовать в await выражении. Многие API-интерфейсы asyncio предназначены для приёма ожидаемых. Существует три основных типа ожидаемых объектов: корутины, задачи и футуры.

Python корутины являются ожидаемыми и поэтому могут ожидаться из других корутин:

В этой документации термин «корутина» может использоваться для двух тесно связанных понятий:

asyncio также поддерживает устаревшие основанные на генераторах корутины.

Задачи используются для конкурентного планирования корутин.

Когда объект Футуры ожидается, это означает, что корутина будет ждать, пока Футура будет решена в каком-то другом месте.

Объекты Футуры в asyncio нужны, чтобы позволить основанному на колбэках коду использоваться с async/await.

Обычно нет нужды создавать объекты Футуры на уровне кода приложения.

Объекты Футуры, иногда раскрываемые библиотеками и некоторыми asyncio API, могут быть ожидаемыми:

Запуск asyncio программы¶

Выполняет корутину coro и возвращает результат.

Функция управляет переданной корутиной, заботясь об управлении asyncio событийного цикла и завершения асинхронных генераторов.

Функция не может быть вызвана, когда в том же потоке выполняется другой asyncio событийный цикл.

Функция всегда создаёт новый событийный цикл и закрывает его в конце. Его следует использовать в качестве основной точки входа для asyncio программ, и в идеале его следует вызывать только один раз.

Добавлено в версии 3.7.

Исходный код asyncio.run() можно найти в Lib/asyncio/runners.py.

Создание задач¶

Обёртывание coro корутины в Task и запланировать её выполнение. Возвращает объект задачи.

Эта функция была добавлена в Python 3.7. Ранее Python 3.7 вместо неё можно использовать низкоуровневую функцию asyncio.ensure_future() :

Добавлено в версии 3.7.

Блокировка на delay секунд.

Если result предоставляется, он возвращается вызывающему после завершения корутины.

sleep() всегда приостанавливает выполнение текущей задачи, позволяя выполнять другие задачи.

Устарело с версии 3.8, будет удалено в 3.10 версии.: Параметр loop.

Пример корутины, отображающей текущую дату каждую секунду в течение 5 секунд:

Конкурентный запуск задач¶

Запускает ожидаемые объекты в последовательности aws конкурентно.

Если какой-либо ожидаемый объект в aws является корутиной, он автоматически назначается как задача.

Если все await объекты выполнены успешно, результатом является сводный список возвращенных значений. Порядок значений результата соответствует порядку await в aws.

При return_exceptions True исключения обрабатываются так же, как и успешные результаты, и агрегируются в списке результатов.

Если gather() отменён, все представленные ожидаемые (которые ещё не завершены) также будут отменены.

Если какая-либо задача или футура в последовательности aws отменена, это рассматривается, как будто сработало исключение CancelledError — вызов gather() не отменяется в этом случае. Это необходимо для предотвращения отмены одной отправленной задачи/футуры, чтобы привести к отмене других задач/футур.

Устарело с версии 3.8, будет удалено в 3.10 версии.: Параметр loop.

Если return_exceptions содержит значение False, отмена gather() после того, как он был помечен как выполненный, не отменит ни одного отправленного ожидаемого объекта. Например, gather может быть помечена как выполненная после передачи исключения вызывающей стороне, поэтому вызов gather.cancel() после перехвата исключения (вызванного одним из ожидаемых объектов) из gather не отменяет другие ожидаемые объекты.

Изменено в версии 3.7: Если gather отменяется, отмена распространяется независимо от return_exceptions.

Защита от отмены¶

Если aw корутина, она автоматически назначается как задача.

Если требуется полностью игнорировать отмену (не рекомендуется), функция shield() должна быть объединена с предложением try/except следующим образом:

Устарело с версии 3.8, будет удалено в 3.10 версии.: Параметр loop.

Таймауты¶

Дождаться завершения aw ожидаемого с таймаутом.

Если aw корутина, она автоматически назначается как задача.

Функция будет ждать, пока футура будет фактически отменена, поэтому общее время ожидания может превысить timeout.

Если ожидание отменяется, то также отменяется и будущий aw.

Устарело с версии 3.8, будет удалено в 3.10 версии.: Параметр loop.

Примитивы ожидания¶

Конкурентный запуск ожидаемых объектов в итерации aws и блокировка, пока не будет выполнено условие, указанное в return_when.

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

return_when указывает, когда функция должна возвращать. Она должна быть одной из следующих констант:

Устарело с версии 3.8, будет удалено в 3.10 версии.: Параметр loop.

Вот как можно зафиксировать вышеуказанный фрагмент:

Не рекомендуется, начиная с версии 3.8: Передача корутиновых объектов непосредственно в wait() устарела.

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

Устарело с версии 3.8, будет удалено в 3.10 версии.: Параметр loop.

Планирование из других потоков¶

Отправить корутину в событийный цикл. Потокобезопасный.

Возвращает concurrent.futures.Future дожидаясь результата из другого потока ОС.

Эта функция вызывается из потока операционной системы, отличного от того, где выполняется событийный цикл. Пример:

Если в корутине возникает исключение, возвращенная футура будет уведомлена. Также можно использовать отмену задачи в событийном цикле:

В отличие от других asyncio функций эта функция требует явной передачи loop аргумента.

Добавлено в версии 3.5.1.

Интроспекция¶

Добавлено в версии 3.7.

Добавлено в версии 3.7.

Объект задачи¶

Задачи используются для запуска корутин в событийных циклах. Если корутина ожидает футуры, задача приостанавливает выполнение корутины и ожидает завершения футуры. Когда выполнено, футура возобновляет исполнение обёрнутой корутины.

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

Устарело с версии 3.8, будет удалено в 3.10 версии.: Параметр loop.

Запрос отмены задачи.

Это позволяет создать CancelledError исключение для обернутой корутины на следующем цикле событийного цикла.

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

Задача отменена, когда запрашивалась отмена с cancel() и обернутая корутина распространила в неё CancelledError исключение.

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

Возвращает результат выполнения задачи.

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

Если задача была отменена, это метод вызывает CancelledError исключение.

Если результат задачи ещё не доступен, это метод вызывает InvalidStateError исключение.

Возвращает исключение задачи.

Если задача была отменена, это метод вызывает CancelledError исключение.

Если задача еще не завершена, это метод вызывает InvalidStateError исключение.

add_done_callback ( callback, *, context=None ) ¶

Добавление колбэка для выполнения при выполнении задачи.

Этот метод должен быть использован только в низкоуровневом основанном на колбэках коде.

Удалить callback из списка колбэков.

Этот метод должен быть использован только в низкоуровневом основанном на колбэках коде.

Возвращает список фреймов стека для этой задачи.

Если обёрнутая корутина не выполнена, он возвращает стек, где он приостановлен. Если короутина успешно завершена или отменена, возвращает пустой список. Если корутина была прервана исключением, возвращает список кадров трейсбэка.

Фреймы всегда упорядочиваются от самых старых до самых новых.

Для приостановленной корутины возвращается только одни фрейм стека.

Необязательный аргумент limit устанавливает максимальное количество возвращаемых кадров; по умолчанию возвращаются все доступные фреймы. Порядок возвращаемого списка различается в зависимости от того, возвращается ли стек или трассировка: возвращаются самые новые фреймы стека, но возвращаются самые старые фреймы трассировки. (Это соответствует поведению модуля трассировки.)

Печать стека или трейсбэка для этой задачи.

Добавлено в версии 3.8.

Возвращает имя задачи.

Если ни одно имя не было явно назначено задаче, реализация задачи asyncio по умолчанию создаёт имя по умолчанию во время создания экземпляра.

Добавлено в версии 3.8.

Задание имя задачи.

Аргументом value может быть любой объект, который затем преобразуется в строку.

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

Добавлено в версии 3.8.

Возвращает множество всех задач для событийного цикла.

Основанные на генераторах корутины¶

Поддержка основанных на генераторах корутин запрещено и планируется к удалению в Python 3.10.

Корутины на основе генератора предшествовали синтаксису async/await. Они представляют собой Python генераторы, которые используют yield from выражения для ожидания футур и других корутин.

Декоратор для маркировки основанных на генераторах корутин.

Этот декоратор обеспечивает совместимость устаревших основанных на генераторах корутин с async/await кодом:

Этот декоратор не должен использоваться для async def корутин.

Устарело с версии 3.8, будет удалено в 3.10 версии.: Используйте async def вместо этого.

Метод отличается от inspect.iscoroutine() потому что возвращает True для основанных на генераторах корутин.

asyncio. iscoroutinefunction ( func ) ¶

Источник

Введение в асинхронное программирование на Python

Всем привет. Подготовили перевод интересной статьи в преддверии старта базового курса «Разработчик Python».

Корутины python что это. Смотреть фото Корутины python что это. Смотреть картинку Корутины python что это. Картинка про Корутины python что это. Фото Корутины python что это

Введение

Асинхронное программирование – это вид параллельного программирования, в котором какая-либо единица работы может выполняться отдельно от основного потока выполнения приложения. Когда работа завершается, основной поток получает уведомление о завершении рабочего потока или произошедшей ошибке. У такого подхода есть множество преимуществ, таких как повышение производительности приложений и повышение скорости отклика.

Корутины python что это. Смотреть фото Корутины python что это. Смотреть картинку Корутины python что это. Картинка про Корутины python что это. Фото Корутины python что это

В последние несколько лет асинхронное программирование привлекло к себе пристальное внимание, и на то есть причины. Несмотря на то, что этот вид программирования может быть сложнее традиционного последовательного выполнения, он гораздо более эффективен.

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

Асинхронность – это одна из основных причин популярности выбора Node.js для реализации бэкенда. Большое количество кода, который мы пишем, особенно в приложениях с тяжелым вводом-выводом, таком как на веб-сайтах, зависит от внешних ресурсов. В нем может оказаться все, что угодно, от удаленного вызова базы данных до POST-запросов в REST-сервис. Как только вы отправите запрос в один из этих ресурсов, ваш код будет просто ожидать ответа. С асинхронным программированием вы позволяете своему коду обрабатывать другие задачи, пока ждете ответа от ресурсов.

Как Python умудряется делать несколько вещей одновременно?

Корутины python что это. Смотреть фото Корутины python что это. Смотреть картинку Корутины python что это. Картинка про Корутины python что это. Фото Корутины python что это

1. Множественные процессы

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

2. Множественные потоки

Еще один способ запустить несколько работ параллельно – это использовать потоки. Поток – это очередь выполнения, которая очень похожа на процесс, однако в одном процессе вы можете иметь несколько потоков, и у всех них будет общий доступ к ресурсам. Однако из-за этого написать код потока будет сложно. Аналогично, все тяжелую работу по выделению памяти процессора сделает операционная система, но глобальная блокировка интерпретатора (GIL) позволит только одному потоку Python запускаться в одну единицу времени, даже если у вас есть многопоточный код. Так GIL на CPython предотвращает многоядерную конкурентность. То есть вы насильно можете запуститься только на одном ядре, даже если у вас их два, четыре или больше.

3. Корутины и yield :

Корутины – это обобщение подпрограмм. Они используются для кооперативной многозадачности, когда процесс добровольно отдает контроль ( yield ) с какой-то периодичностью или в периоды ожидания, чтобы позволить нескольким приложениям работать одновременно. Корутины похожи на генераторы, но с дополнительными методами и небольшими изменениями в том, как мы используем оператор yield. Генераторы производят данные для итерации, в то время как корутины могут еще и потреблять данные.

4. Асинхронное программирование

Четвертый способ – это асинхронное программирование, в котором не участвует операционная система. Со стороны операционной системы у вас останется один процесс, в котором будет всего один поток, но вы все еще сможете выполнять одновременно несколько задач. Так в чем тут фокус?

Asyncio – модуль асинхронного программирования, который был представлен в Python 3.4. Он предназначен для использования корутин и future для упрощения написания асинхронного кода и делает его почти таким же читаемым, как синхронный код, из-за отсутствия callback-ов.

В следующем примере, мы запускаем 3 асинхронных таска, которые по-отдельности делают запросы к Reddit, извлекают и выводят содержимое JSON. Мы используем aiohttp – клиентскую библиотеку http, которая гарантирует, что даже HTTP-запрос будет выполнен асинхронно.

Использование Redis и Redis Queue RQ

Использование asyncio и aiohttp не всегда хорошая идея, особенно если вы пользуетесь более старыми версиями Python. К тому же, бывают моменты, когда вам нужно распределить задачи по разным серверам. В этом случае можно использовать RQ (Redis Queue). Это обычная библиотека Python для добавления работ в очередь и обработки их воркерами в фоновом режиме. Для организации очереди используется Redis – база данных ключей/значений.

В примере ниже мы добавили в очередь простую функцию count_words_at_url с помощью Redis.

Заключение

В качестве примера возьмем шахматную выставку, где один из лучших шахматистов соревнуется с большим количеством людей. У нас есть 24 игры и 24 человека, с которыми можно сыграть, и, если шахматист будет играть с ними синхронно, это займет не менее 12 часов (при условии, что средняя игра занимает 30 ходов, шахматист продумывает ход в течение 5 секунд, а противник – примерно 55 секунд.) Однако в асинхронном режиме шахматист сможет делать ход и оставлять противнику время на раздумья, тем временем переходя к следующему противнику и деля ход. Таким образом, сделать ход во всех 24 играх можно за 2 минуты, и выиграны они все могут быть всего за один час.

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

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

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *