**Многопроцессность, многопоточность, асинхронность в Python и не только. Что это и как работает? — Transcript & Summary | SozAI**
Source: https://sozai.app/transcript/multiprocessing-multithreading-asynchrony-python/

Видео о конкурентности в Python: различия многопроцессорности, многопоточности и асинхронности, устройство процессов и потоков, GIL и практические примеры.

## Key Takeaways

- Конкурентность не означает обязательного параллельного выполнения задач
- Процессы изолированы друг от друга, что повышает безопасность и стабильность
- В Python GIL ограничивает параллельное выполнение потоков, поэтому для CPU-задач используют процессы
- Асинхронность эффективна для задач с ожиданием ввода-вывода и имеет меньшие накладные расходы

## What the video covers

- Введение в конкурентность как способность управлять несколькими задачами в перекрывающиеся периоды времени, без обязательного одновременного выполнения
- Визуализация работы многоядерных процессоров и распределения задач по ядрам
- Историческое развитие: от последовательного выполнения на одноядерных системах к переключению контекста
- Разница между конкуренцией за процессорное время и реальным параллелизмом
- Определение процесса как запущенной программы с изолированными ресурсами памяти
- Аналогия процесса и потоков с офисной работой и сотрудниками
- Потоки внутри процесса и их разделение ресурсов
- Глобальная блокировка интерпретатора (GIL) в Python и её влияние на многопоточность
- Многопроцессорность для CPU-bound задач и пул процессов
- Асинхронность для I/O-bound задач и сравнение накладных расходов с потоками

## Chapters

1. 00:00 Введение и определение конкурентности
2. 03:00 Многоядерные процессоры и распределение задач
3. 06:10 Эволюция: от последовательного выполнения к переключению контекста
4. 12:00 Потоки и их устройство внутри процесса
5. 19:00 GIL и многопоточность в Python
6. 27:30 Многопроцессорность и пул процессов
7. 39:20 Асинхронность и asyncio

Answers

## Questions about this video

Что такое конкурентность согласно видео?

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

Чем процесс отличается от потока?

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

Почему в Python для CPU-задач рекомендуют многопроцессорность?

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

## Full Transcript — Download SRT & Markdown

00:00

Speaker A

те зрители которые досмотрят это видео до самого конца узнают что такое конкурентность И зачем она нужна Что такое многопроцессорность друзья Добро пожаловать на канал АйТи изм на канал инженерной культуры доступной каждому Меня зовут Николай Свиридов я Python backend разработчик и мы

00:21

Speaker A

начинаем и начинаем мы с вами с нашего основного понятия вокруг которого сегодня пойдёт Всё повествование - Это конкурентность я думаю так или иначе вы сталкивались с ней где-то может быть на собеседованиях может быть где-то в работе и что это такое Это концепция в

00:39

Speaker A

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

00:57

Speaker A

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

01:16

Speaker A

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

01:32

Speaker A

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

01:51

Speaker A

происходит выполнение кусочков этих задач то есть кусочек от жёлтой задачи выполнило на Первом ядре потом кусочек от зелёной задачи потом кусочек от потом от зелёной потом опять от красной потом от синей второе ядро синее жёлтое синее серое жёлтое синее Ну и с третьим ядром

02:08

Speaker A

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

02:26

Speaker A

идёт вычисление положение например вашего героя обсчёт механики NPC выстрелов всего остального и после того как это всё обсчитали Зро отправить вам на экран и Если бы у нас не было хорошо работающей конкурентности и Мо мощного компьютера то у вас сначала бы всё

02:47

Speaker A

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

03:12

Speaker A

чтобы вы написали в комментариях друзья когда-нибудь было у вас случай столкнуться с конкурентностью Может быть вы в своих рабочих проектах это используете Может быть вы в ПД проектах это делаете Может быть на собеседовании Вам задавали вопрос связанный с

03:26

Speaker A

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

03:46

Speaker A

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

04:11

Speaker A

начать задачу номер два Ну и дальше задачу номер четыре и так далее И эти задачи как я вот внизу внизу написал задачи в скобочках процессы мы поговорим сейчас что такое процессы в них выполнялись последовательно от начала и до конца То есть я думаю это довольно

04:29

Speaker A

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

04:46

Speaker A

основном своём канале ролик про потоки процесса И вот я на примере там кофеварки и варки пельменей ответа по телефону рассказывал одну из концепций которая используется в конкурентности про которую мы тоже сегодня поговорим что же произошло дальше наши ядра

05:04

Speaker A

становились мощнее и мощнее и люди придумали переключение контекста между нашими задачами и сказали Ну если очень быстро переключаться Между этим контекстом то люди наверное не заметят Как там чего происходит и соответственно будет создаваться такое впечатление что у нас выполняется много задач прям вот

05:22

Speaker A

прям вот как будто бы Прямо одновременно и здесь мы видим то что мы уже полили задачу один и задачу 2 на кусочки то есть сделали кусочек задачи один потом переключились на задачу два потом опять на задачу один потом опять на задачу два

05:35

Speaker A

и так далее до того момента пока задачи наши не будут выполнены и при этом это вот кто-то скажет ой у нас задачи выполняются в параллель Но на самом деле это не так нет задачи выполняются конкурентно то есть они конкурируют За

05:51

Speaker A

что За процессорное время То есть им выделяется квант этого времени для того чтобы они что-то поделать и дальше отдали контекст выполнения в другую задачу красными точками помечены у нас места переключения контекста между нашими задачами опять же в скобочках

06:08

Speaker A

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

06:26

Speaker A

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

06:44

Speaker A

есть что-то общее между этими словами один и тот же корень корень процесс так вот процесс - это атомарная единица бытия того что происходит у вас в ваших мобильных телефонах компьютерах да В чём угодно это по сути программа во время её

07:02

Speaker A

выполнения Когда вы запускаете любую программу на компьютере операционная система создаёт для неё процесс Это означает что программа получает выделенное пространство в памяти и ресурсы которые необходимы для того чтобы она могла корректно отработать и сделать ту задачу которую вы на неё

07:23

Speaker A

возложили что важно помнить что процессы они товарищи которые полностью изолированы друг от друга Что крайне хорошо для безопасности и стабильности работы наших программ То есть когда вы запускаете Microsoft Word - Это у вас один процесс Когда вы запускаете

07:37

Speaker A

какой-нибудь Zoom Skype и других товарищей - это процессы которые друг от друга не зависят Ну было бы не очень хорошо Наверное если вы закрываете Microsoft Word или он у вас падает с ошибкой И тут у вас руинит ещё

07:51

Speaker A

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

08:11

Speaker A

сотрудник за работой в офисном помещении А с его рабочим местом где есть компьютер где есть всякая канцелярка В общем стулстол всё что только возможно и заданиями которые этот самый сотрудник выполняет всё это устроено так что сотрудник программа процесс мог

08:33

Speaker A

эффективно справляться со своими обязанностями и прежде чем мы пойдём дальше друзья я хочу сказать что у нас есть Telegram канал itm Movement где есть много-много интересного мы пишем туда посты выкладываем всякие анонсы поэтому присоединяйтесь к нашей инженерной культуре доступной каждому и

08:54

Speaker A

вы скажете Ну хорошо вот есть сотрудник всё классно он там делает свои задачи но Коль допустим с процессами понятная история в целом то что мы запустим программу она будет там что-то выполнять и вот это вот процесс но есть какие-то

09:10

Speaker A

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

09:30

Speaker A

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

09:50

Speaker A

вот у нас была задача один задача д мы переключаем между этими процессами туда-обратно это довольно-таки существенные накладные расходы для на компьютера Ну опять же есть задачи где мы вынуждены это делать мы поговорим об этом тоже сегодня есть задачи где это не

10:07

Speaker A

целесообразно делать и появляется ещё одна сущность которая называется поток то есть что люди сказали ну как бы это всё здорово когда у нас есть два процесса и два офисных сотрудника которые сидят у нас в одном и том в одном и том же офисном

10:26

Speaker A

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

10:41

Speaker A

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

11:02

Speaker A

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

11:21

Speaker A

пользоваться в таком количестве но мы вынуждены выдать и первому сотруднику и второму рабочее помещение и первому и второму и это может быть очень на Ладно если мы поместим их в одно помещение это будет для нас более выгодно и Здесь люди

11:35

Speaker A

сказали так А давайте придумаем такую же сущность как и процессы вот с точки зрения высокоуровневый архитектуры это будет Вот то же самое по логике То есть это будет единица запущенной программы но в чём история давайте сделаем так чтобы несколько вот

11:55

Speaker A

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

12:14

Speaker A

очень такая тяжёлая была для меня концепция Потому что я не понимал как это потоки живут внутри процесса Но вот здесь представьте себе даже историю не с департаментом а историю с тем что вот у вас есть Автомобиль в котором есть руль

12:29

Speaker A

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

12:53

Speaker A

говорите Нет это всё моё вы там себе мощный двигатель организуете и вот с ним ездите во Представьте что мы берём такую н Панков историю и говорим Ну у тебя же есть вот этот двигатель Да дай нам Им попользоваться

13:04

Speaker A

и вы говорите Ладно Хорошо уговорили и вот представьте себе два автомобиля без двигателей но с рабочей какой-нибудь ходовой частью и вы вот так вот знаете сбоку ставите вот у вас автомобиль по центру ещё два автомобиля сбоку такой сэндвич из автомобилей но пользоваться

13:20

Speaker A

они бу будут двигателем и топливом вот одного главного автомобиля то есть они будут от него зависимы и они будут получаться сожительство все вместе И разумеется здесь обратной стороной будет являться то что если двигатель выйдет из строя то сразу же поломается всё во всех

13:40

Speaker A

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

13:59

Speaker A

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

14:32

Speaker A

вот В подобном контексте тоже идёт переключение этого самого контекста на ядрах и вы скажете Ну вот здесь-то наверное уже параллельность происходит и Действительно это так с этого момента можно стало официально говорить о том что в один момент времени в компьютере

14:47

Speaker A

выполняется Сразу две задачи параллельно Как понять параллелизм у нас или не параллелизм мы берём и проводим вот э вот строим график и выстраиваем вот эти как они выполняются кусочки а потом сверху вниз проводим черту и смотрим А сколько у нас задач рассекает эта самая

15:08

Speaker A

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

15:27

Speaker A

в рамках одного единственного и мы пришли туда откуда Мы начинали У нас есть многоядерный процессор у нас есть конкретный момент времени и в зависимости от того Какое количество ядер у нас В нашей машине присутствует Мы видим что рассека может и две и три

15:45

Speaker A

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

16:02

Speaker A

Понятно зачем нам процессы Да с потоками может быть не очень понятно а там вот ещё есть какая-то асинхрон значит начнём с того что все задачи которые у нас выполняются на нашем компьютере можно разделить на две большие группы это CPU Bound задачи

16:18

Speaker A

это задачи которые сопряжены с вычислениями которые выполняются исключительно на стороне вашего компьютера они утилизируют ресурсы вашей машины на эти самые то есть когда вы молоте какие-то математические операции прямо очень сильно молоти у вас процессор загружен вот 100% времени ему чем ему есть чем

16:41

Speaker A

заняться но есть также inp output Bound а Bound задачи они дословно перевод задачи ввода-вывода большая часть времени выполнение этих задач уходит на ожидание ответа от чего-то внешнего например от веб-сервиса базы данных Чего угодно Это всё что связано с нашим прекрасным интернетом

17:06

Speaker A

которым мы пользуемся прямо вот в тот момент времени В который вы сейчас смотрите этот ролик а потому что потому что потому что вы очень много ждёте Когда вы открываете свой браузер у вас очень быстро формируется запрос от вас

17:22

Speaker A

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

17:39

Speaker A

он ожидает и больше и больше ничего так вот это выглядит как-то не очень эффективно И разумеется здесь можно подойти и со стороны процессов и стороны со стороны потоков заметьте мы не говорим сейчас про Python мы говорим в целом про вот эти верхнеуровневый вещи

18:01

Speaker A

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

18:16

Speaker A

нашего сервера Я вас не хочу расстраивать но скорее всего у нас машина прилягають довольно-таки эффективно с одной стороны с другой стороны если например смотреть на язык разработки Python то потоки у нас из-за того что я думаю вы слышали про глобальную

18:38

Speaker A

блокировку интерпретатора в питоне это организовано так что Ну к сожалению мы не можем это сделать ээ в параллель прямо в реальную потому что глобальная блокировка интерпретатора говорит что только один поток Может в один момент времени выполняться Почему так сделали

18:56

Speaker A

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

19:15

Speaker A

к нехорошей не консистентной ситуации Вот Но про Гил можно говорить отдельно это достойно одного большого ролика так вот и в асинхронность плюс ко всему есть ещё такой момент что она не тратит ресурсы на переключение контекста пока мы ещё даже про асинхронность не

19:38

Speaker A

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

19:51

Speaker A

про большое количество запросов отправляемых с клиента а потоки Ну не везде их Можно например вот прямо распараллелить то есть это будет не очень эффективная утилизация ресурсов с одной стороны с другой стороны ВС равно потоки требуют накладных расходов на

20:10

Speaker A

переключение контекста между ними что с ростом активности пользователей в интернете стало тоже довольно критически важным фактором и какое было предложено решение через ан через асинхронность скажу что это не только штука которая используется в питоне есть ещё языки разработки

20:33

Speaker A

которые её так или иначе иначе реализуют синхронность говорит примерно следующее Зачем мне ждать ответа на мой запрос если я могу его не ждать а пойти закинуть ещё несколько каких-то задач несколько запросов и ожидать ответа на них одновременно и Давайте посмотрим как

20:52

Speaker A

это выглядит графически в принципе синхронное выполнение против асинхронного здесь у нас такая общая картинка она будет на самом деле она даже будет справедлива для использования в там в потоках но здесь я про всё-таки про асинхронность мы говорим значит если у нас синхронное

21:13

Speaker A

выполнение одно идёт за другим вот запрос ожидание ответа запрос ожидание отве ответа и обработка информации то есть красным у нас выделены вот эти вот куски это когда у на Работает наша программа она делает какую-то полезную работу здесь маленькая еле заметная

21:31

Speaker A

узкая черта Вот эта полосочка - Это запрос по сети он делается очень быстро и после этого у нас идёт ожидание ответа которое Ну бывает довольно-таки большим так вот если мы будем ждать ответа синхронно посмотрите сколько времени мы потратим если мы будем

21:46

Speaker A

говорить что вот сделали полезную работу бросили запрос опять сделали полезную работу бросили запрос то у нас всё это будет упаковано очень компактно и дальше получив ответ Мы каждый из них сможем обработать И как же устроен ан aio в

22:02

Speaker A

питоне Ну и вообще в других языках разработки чаще всего А верхнеуровнево у нас есть какая-то всякая полезная работа на стороне программы и есть Event loop - это цикл событий что говорит этот цикл событий он говорит примерно следующее вы дадите мне

22:20

Speaker A

вашу работу Где внутри этой работы будет команда на переключение контекста что я могу заняться чем-то ещё и чаще всего мы используем не чаще всего А мы используем асинхронный подход для Input output Bound операций для того чтобы отправлять данные по сети то есть

22:38

Speaker A

мы можем закинуть эти данные мы можем дождаться ответа и потом мы можем эти данные прочитать что-то с ними сделать вот в момент когда мы формируем запрос и кидаем этот запрос по сети мы используем сокеты сетевые не блокирующие которые

22:54

Speaker A

есть в каждой операционной системе и эти сокеты они находятся на стороне ну операционной системы Точно точно так же как потоки процессы это всё управляется Уэй Вот и вот этот Event loop он говорит я не буду дожидаться пока там что-то

23:08

Speaker A

появится я пойду ещё запрос кину а потом как только мне как только данные придут на какой-то соке меня об этом уведомит и дальше я уже продолжу свою работу в контексте тех данных которые я запрашивал у серверной страны вот меня

23:24

Speaker A

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

23:36

Speaker A

продолжить слушать эти самые события Ну и ребят время теперь посмотреть код как значит как всё это варить И начнём мы с примера с процессами значит в питоне процессы представлены с помощью модуля multiprocessing и тут есть обёртка над процессами Вот такая мульти процессинг

23:58

Speaker A

имр process и здесь очень простая задача то есть сам CP Bound Task здесь мы суммируем от одного до n числа понятно что есть формула сумма ряд Но мы её не используем что мы делаем мы говорим что мы создаём эту обёртку process мы отдаём

24:16

Speaker A

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

24:39

Speaker A

это объект обёртка Это не сам ещё процесс но когда мы говорим Старт Это значит что мы запускаем дочерний процесс и если вы пойдёте в диспетчер задач Когда вы дойдёте до старта если у вас тут будет большое число то вы увидите

24:55

Speaker A

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

25:16

Speaker A

используем Join для чего для того чтобы ну дождаться Я хочу дождаться выполнения процесса который Мы создали в четырнадцатой строчке в шестнадцатой запустили Потому что если мы не сделаем Join то наш процесс который главный он конечно дождётся выполнения дочернего но

25:34

Speaker A

он смотрите он даст нам неправильное Время ожидания неправильное время работы нашей программы То есть тут 25,6 секунд если мы уберём Join он сразу нам выдаст вот это вот очень маленькое время Вы подумаете что Ну так оно и должно быть

25:48

Speaker A

на самом деле на самом деле нет нужно дождаться завершения дочернего процесса и только тогда посчитать общее время выполнения вот а идём дальше допустим Здесь мы запускали в отдельном процессе какую-то задачу но у нас же может быть допустим я хочу распараллелить Три вот

26:10

Speaker A

этих пу Bound таски А мы можем это сделать путём того что мы будем запихивать наши процессы в process list То есть я натол кал это всё в process list давайте я сразу запущу значит я налка это всё в process L

26:27

Speaker A

дальше я сказал что кажды процес который я туда клал я стартовал и поскольку здесь я не делаю Join то я могу спокойно уходить на следующую итерацию цикла а потом уже итерироваться по process list и дожидаться каждого из этих процессов И

26:44

Speaker A

как только все процессы завершили свою работу мы говорим Total execution Time подсчитывая всё это дело и отображая это всё на экране и вот мы видим что здесь я вижу идентификаторы своих процессов дочерних То есть я прокиды это в

26:59

Speaker A

качестве параметра N А ну нет в качестве параметра N я прокиды значит суммирование но здесь у нас есть с помощью osg process ID я могу запросить дишни процесса в котором выполняется именно эта функция Вот мы видим что шники у нас разные при этом время

27:16

Speaker A

выполнения 36 секунд То есть Оно конечно больше чем если мы с одним работали бы процессом но тем не менее если мы умножим там 25 секунд на 3 мы получим 7 55 секунд но никак не 36 То есть у нас здесь есть действительно

27:31

Speaker A

выигрыш по вот этой цпу Bound задаче но есть ещё более удобная вещь для работы с процессами - это пул процессов Когда вам не нужно создавать вот такую вот ручную манипуляцию со стартом и Джоном мы говорим что импортируем из мульти

27:48

Speaker A

процессинга пул мы говорим то что задаём размер Пула 3 процесса и дальше с помощью команды Pool Map запускаем одну и ту же функцию То есть у нас функция во всех процессах одна и та же будет работать сам CP Bound Task это как раз

28:02

Speaker A

кей Когда вы запускаете в процессах что-то одинаковое то вы можете воспользоваться пулом процессов и дальше мы прокиды аргументы но здесь я взял список умножил его на количество процессов три То есть это кортеж с аргументами таким список с аргументами

28:21

Speaker A

для каждого из наших э сам CP Bound Task То есть это будет первый аргумент из нашего списка с аргументами потом опять сампу Bound Task и второй и третий и так далее и так далее значит после этого печатаем результат мы с вами обязательно его

28:40

Speaker A

увидим И после этого мы опять же подсчитывая общее время выполнения Ну давайте здесь я поменьше поставлю число чтобы нам так долго не ждать запускаем Вот мы видим что везде он [музыка] а правда ли у нас а тут до получается до

29:02

Speaker A

ТХ Ну тут видимо как-то нулей тут очень мало Хотя 3 ну 6 Ну 6 Ну Миллион Ну в общем он всё равно так или иначе он всё это дело обсчитывают давайте я тут попробую поставить один 10 млн вот оно будет подольше

29:20

Speaker A

работать но он сам О Видимо да Дада всё правильно всё правильно он всё правильно обет не сумма ряда тут Конечно же это просто большое количество единиц у меня в списке Конечно же он мне вернёт ровно то же самое что будет здесь то есть у меня

29:36

Speaker A

сумма будет равна N но нормально Это синтетический пример который нам вполне с вами подходит и здесь мы говорили про цпу бауд задачи А теперь давайте рассмотрим небольшой пример для запросов по сети У меня есть сайт example.com Вы можете туда зайти это просто сайт на

29:53

Speaker A

который можно кидать какие-то типовые запросы и мы с вами опять количество процессов только теперь мы будем бросать запросы по сети возвращать статус код запускаем и я здесь мули задержку через та СП чтобы мы с вами Поспали и посмотрим Сколько времени у нас займёт

30:13

Speaker A

выполнение значит опять номера процессов и мы видим с вами Что за 3 секунды 25х у нас произошло выполнение номер процесса и спали мы сколько с вами то есть передали нам да Мы спали с вами Т 3 секунды А нам

30:34

Speaker A

получается вообще не нужно а нет хотя соврал соврал давайте давайте посмотрим поде бажи обязательно остановимся здесь N = 1 Он будет спать одну секунду Значит у нас с вами произошло произошла ситуация при которой у нас наши процессы отработали так тут

30:53

Speaker A

10 секунд из-за того что я дежи Давайте пере запустим Давайте посмотрим что время выполнения одну секунду заняло 1 секунду 64 соток Почему в первый раз 3 секунды было Ну а потому что опять же Ну то есть тут не будет ровно такое что прямо вот

31:09

Speaker A

всё в параллели значит 1 секунда будет на всё не всегда это получается давайте мы поставим время сна Ну допустим не одну секунду а там 3 секунды чтобы это было более явно то есть Я предполагаю что где-то там в 5 секунд мы сейчас

31:23

Speaker A

уложимся хотя даже быстрее видите э 3,75 Хотя каждый из запросов у нас занимал из-за того что мы здесь поставили тройку он занимал у нас с вами не менее 3 секунд это очевидно вот Ну как я уже сказал Если вы поставите здесь большое

31:39

Speaker A

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

31:59

Speaker A

Ваш компьютер может убежать вут вот для запросов по сети как я говорил очень эффективно бывает использовать потоки потоки очень похожи по синтаксису на процессы то есть используется Единственное что модуль Н И в остальном всё тоже самое тред Таргет аргументы

32:18

Speaker A

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

32:37

Speaker A

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

32:54

Speaker A

потоки разделяют ресурсы процесса иль одни и теми же нитками которые там лежат вот общее время выполнения здесь у нас 22 секунды я думаю что это вполне нормально потому что мы выполнили цпу баун задачу да то есть это не а Бау задача опять Мы

33:11

Speaker A

молотим пушку Ну как я сказал никакого на самом деле смысла это делать здесь нет если мы сейчас запустим здесь вот три потока одновременно Мы с вами Увидим что будет всё довольно довольно долго делаться Ну вот смотрите здесь Единственное что неправильно почиталось

33:27

Speaker A

Почему я треды свои не сжо Ил То есть я сделал три треда лист я добавил но не написал значит пока пускай он считает я напишу for thad in thad list и напишу thad Join вот чтобы мы каждого из них

33:47

Speaker A

дожидались ну и давайте я поставлю число поменьше вот 1 млн поставлю А значит ну 1 млн мало Давайте 10 млн Чтобы хоть какая-то задержка была вот задержка пошла 0,62 а если 100 в 10 раз дольше вот он все три их кажется что они все

34:04

Speaker A

три запустили и они прямо в параллель считают эти числа Ребята Не обманывайтесь вот тут вот у нас 6 секунд получилось давайте мы поставим тот же самый N и вернёмся к допустим полу процессов и list of processes Давайте list of processes и поставим здесь 100

34:21

Speaker A

получается 100 млн здесь 6 секунд У нас было давайте запустим наши процессы секун 6 секун а тут 2 секунды видите в три раза Ну как раз как я сказал что потоки у нас не дают выигрыша вот мы три

34:35

Speaker A

потока три процесса соответственно в три раза дольше у нас получилось с потоками выполнения CP Bound задачи но при этом есть ещё такая же история как и с пулом процессов а не чтобы можно было не запускать руками всю эту историю есть

34:52

Speaker A

такая штука threadpool execut которая находится в библиотеке concurrent futures RP execut который под капотом эти потоки сами сам запускает и здесь у нас количество воркеров количество потоков три максимальная вот мы возвращаем л и с помощью хорошо нам знакомой истории smap вот когда мы

35:13

Speaker A

запускали наши процессы тоже пользовались МАПО но только у Пула процессов и синтаксис точно такой же при этом здесь смотрите я сразу же здесь здесь если мы будем использовать сам CP Bound Task мы получим такое же плохое время как и в

35:34

Speaker A

ситуации с нашими обычными потоками но если мы используем сам iob Task который делает запросы по сети и допустим СПИД получается тут одну секунду давайте мы поставим сон 3 секунды Давайте посмотрим Сколько времени у нас займёт отправка запросов Я предполагаю что где-то за Ну

35:54

Speaker A

вот 3,5 секунды у нас ушло То есть если бы мы делали баун задачу при этом у нас такого выигрыша Ну не получилось потому что у нас Гил блокирует и И всё И мы Встаём в раскар мы меняем контекст между

36:08

Speaker A

процес потоками и возникает вот эта беда то есть здесь я надеюсь что я не оговаривался насчёт потоков и процессов здесь мы работаем с потоками то есть пул потоков точно также как с пулом процессов Мы работаем но здесь потоки Это другая другая сущность

36:28

Speaker A

кото разделяет ресурсы процесса И последнее что мы с вами можем здесь посмотреть это так Ну как я уже сказал это да этот приме пример мы уже рассмотрели request with threads асинхронность теперь переходим к асинхронность и Давайте посмотрим на то

36:46

Speaker A

Как организован код с ан ан использует свои собственные объекты которые называются корутины корутины получаются из функций которые помечены ключевым словом перед финишем этим этой самой функции и включают в себя какую-нибудь штуку которая помечена с каким-нибудь итом Это асинхронное

37:09

Speaker A

ожидание у нас сегодня разговор не про то как пользоваться асин А про вот концепцию Да что нам предлагает As предлагает нам во-первых специфически но всё-таки Дружелюбный по сравнению с тем что было раньше синтаксис который позволяет писать д и говорит что ну ребят просто

37:31

Speaker A

Возьмите запихивает он в асинхронную функцию вызовите эту историю и будет вам счастье Значит первое что мы попробуем сделать это засунуть цпу Бау задачу В нашу асинхронную функцию и здесь никакого выигрыша у нас не будет то есть если сам

37:55

Speaker A

Task мы запускаем мы с вами увидим то что он скажет процесс такой-то запущен это наш А значит это онко цпу это мы видим то что на самом деле процесс тут никакой даже не порождается у нас в рамках выполнения асинхронного кода один поток

38:15

Speaker A

один процесс ничего никаких там переключений контекстов нет только Event loop который работает и опрашивает ждёт влетевшего в него события 30 не 37 22,8 практически секунды у нас заняло время выполнения нашего кода с CP Бау задачи асинхронность вам не поможет с CP

38:36

Speaker A

Бау задачами не нужно её использовать она поможет только в случае с вашими запросами по сети а запросы по сети как их можно эффективно воспроизвести в случае с инпут с нашей ан библиотекой есть асинхронный слип то есть Я не стал сознательно усложнять код

39:00

Speaker A

использованием библиотеки I http либо каких-то других сущностей асинхронных просто представим что у нас есть Запрос который выполняется одну секунду и с помощью библиотеки aso там есть асинхронный слип это слип который не блокирует Он позволяет нам Ну вернуть контекст исполнения обратно в наш Event

39:21

Speaker A

loop и с помощью специального синтаксиса Мы сначала создали точно так же как вот мы обёртки для процессов создавали для потоков создавали а потом мы приговаривал нени здесь можно сформировать группу асинхронных задач они называются рутины но есть ещё и

39:39

Speaker A

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

39:56

Speaker A

запускаем мы видим сообщение emulate of http request и время выполнения 4 секунды то есть смотрите у нас даже нет вот этих накладных расходов там в полсекунды там ещё во сколько-то то что мы видели на потоках и на ну на

40:12

Speaker A

процессах мы а Bound задачи не смотрели вот именно нет вот этого хвоста от потоков То есть у нас асинхронность работает быстрее но вы зададите вопросом а потоки вообще используют да ребята Их используют Их используют довольно активно есть фреймворки которые

40:28

Speaker A

используют потоки например фласк Наш замечательный и вы скажете А зачем вот когда нужны потоки ребят Самое главное когда нужны потоке Когда у вас нет реализованных решений под он плюс ан оно всё-таки требует определённой сноровки для того чтобы работать с ним и требует

40:46

Speaker A

определённого ценза опять же компетенции знаний хотя за последнее время как я сказал Син уже довольно-таки дружелюбная библиотека которую не скажу что стыдно не знать но хорошо бы её осваивать но там очень много интересного нужно хорошо понимать как работает сеть для того

41:03

Speaker A

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

41:20

Speaker A

asino лучше использовать его использовать он если у вас очень большие ожидания Ну не в смысле что Как ускорить свою программу а ожидания сетевые то есть что у вас там задержка не знаю несколько секунд это точно про asino если у вас сетевая задержка маленькая то

41:37

Speaker A

в принципе можно использовать и потоки а особенно потоки можно использовать Когда у вас нет готового решение под ан весь код у вас допустим асинхронный И вам у вас не получается внедрить туда решение на asino потому что его нету И вы берёте

41:55

Speaker A

и вы можете в рамках asino например запустить ть потоки это тоже практикуется Ну что друзья Спасибо большое что посмотрели Подписывайтесь на наш канал ставьте колокольчик любите айтиш Всем пока

Topics: конкурентность многопоточность многопроцессорность асинхронность Python GIL процессы потоки asyncio параллелизм

Учить по этому видео

- [Карточки по этому видео](https://sozai.app/ru/tools/flashcard-maker/?from=transcript&id=94233)
- [Тест по этому видео](https://sozai.app/ru/tools/quiz-generator/?from=transcript&id=94233)
- [Кроссворд по этому видео](https://sozai.app/ru/tools/crossword-maker/?from=transcript&id=94233)
- [Филворд по этому видео](https://sozai.app/ru/tools/word-search-maker/?from=transcript&id=94233)
- [Шпаргалка по этому видео](https://sozai.app/ru/tools/study-guide-maker/?from=transcript&id=94233)

Бесплатно, составлено ИИ по этой расшифровке. Без регистрации.


---
This is the markdown twin of https://sozai.app/transcript/multiprocessing-multithreading-asynchrony-python/ — the same content, without the markup.
Published by SozAI (https://sozai.app). Reuse and quotation are allowed with attribution and a link back.
Machine-readable index: https://sozai.app/llms.txt · data API: https://sozai.app/api/
