Asyncio, threading, multiprocessing — как пользоваться
В этой статье мы коротко разберем такие библиотеки, как asyncio, threading, multiprocessing, коротко о них и как работают.
прОцесс пошел!
1.Asyncio
asyncio - библиотека, которая работает в режиме цикла событий с незаблокированным API,все события работают в 1 потоке в асинхронном режиме.
asyncio выполняет задачи в однопоточно-асинхронном режиме, если где-то наступает момент ожидания, программа переключается на другую задачу, чтобы потом вернуться обратно к моменту, где было ожидание, НО, это переключение произойдет только когда выполниться та задача, на которую программа переключилась в момент ожидания.
Приведу визуальный пример, а потом мы его рассмотрим в коде
1) Выполняем часть задачи в функции ivan и начинаем ждать «что-то»
2) Пока ожидается «что-то» в функции ivan, происходит переход к выполнению задачи в функции car, тут выполняется часть задачи и мы начинаем ждать там «что-то», в этот момент происходит переход обратно к функции ivan
3)Так как мы перестали ждать «что-то" в функции ivan, завершаем задачу, пока функция car ждала "что-то», задача в функции ivan завершилась.
4) Функция car перестает ждать «что-то», и до конца выполняется задача
2.Threading
threading — библиотека, которая позволяет работать с несколькими потоками(количество ограничено только возможностями вашей машины).
Здесь нет асинхронной работы, просто каждая задача запускается в отдельном потоке, где все потоки работают параллельно(почти)
Упс… упираемся в GIL при многопоточной работе… как же так ?!
Сколько бы вы не создавали потоков в Python, все это будет скомкано в GIL, где в реальном времени может работать только 1 поток, просто во время работы программы будет происходить переключение между этими потоками.
Приведу визуальный пример
Тем самым возникает вопрос, ускоряет ли многопоточность в Python работу кода ? - Нет, если не во всех, то в большинстве случаев замедляет.
Возникает второй вопрос, зачем тогда нужна многопоточность в Python ? - Если нужно например выполнение нескольких целей параллельно, то threading для этого отлично подходит, в отличие от multiprocessing.
Запускаем задачу в разных потоках вот так:
3. Multiprocessing
multiprocessing - библиотека, которая позволяет работать в многопроцессорном режиме.
В отличие от библиотеки threading, multiprocessing ускоряет работу Python кода, но в урон большего потребления ресурсов.
Почему многопроцессорность позволяет ускорить работу Python, а многопоточность нет ?
Когда вы запускаете многопроцессорный код, каждый процесс имеет свои ресурсы и свой GIL, именно из-за этого происходит большее потребление ресурсов.
Когда вы запускаете многопоточный код, все потоки скомкиваются в 1 GIL, где просто происходит переключение между ними.
Каждый процесс работает только с теми ресурсами, которые вы ему предоставите, например если вы передали в 1 процесс одни параметры а во 2 процесс другие, они смогут этими ресурсами обменяться только через канал, и именно поэтому если цель - параллельная работа, лучше использовать threading, чтобы не писать лишний код для обмена данных между процессами.
Приведу визуальный пример работы многопроцессорности
Как вы видите, при запуска каждого процесса запускается свой GIL, что позволяет каждому процессу занимать весь GIL и ни с кем не делиться ;)
Тестим скорость работы в многопроцессорном режиме и однопроцессорном режиме -
код:
результат:
При запуске текущего кода на нескольких процессах - код работает в 3 раза быстрее!
Как обмениваться данными между процессами ?
Есть три известных способа Queue, JoinableQueue и SimpleQueue, о них подробно тут -
Мы рассмотрим только 1 - Queue:
Мы создаем канал queue и с помощью него берем данные из одного процесса и передаем в другой.
Если моя статья кому-то пригодилось или внесла ясность в голову, для меня это лучший подарок, но от комментариев, подписки и кармы я не откажусь ;)
Всем удачи!