CPU, Memory Models, Concurrency, Multiprocess, Multithreading и Async. Часть 10. Fibers и виды многозадачности.
Настало время погрузиться в то, как устроены примитивы исполнения на уровне ЯП. И первое что нужно сделать это установить терминологию.
Какие потоки исполнения существуют в рамках любой программы?
• Поток ОС (поток, предоставленный нам ОС)
• Аппаратный поток (фактический физический поток на ЦП)
• Fiber-поток (поток исполнения в нашей программе)
Fiber — это, по сути, обозначение в Computer Science любых легковесных потоков исполнения. Далее буду использовать это термин для обозначения любых рантайм потоков исполнения. Если говорить грубо, то fiber-потоками можно назвать корутины, горутины, тасклеты, зеленые потоки. У них у всех есть некоторые различия, но суть остается той же.
Ок, мы получили в свое распоряжение файберы, теперь нужно разобраться как в коде организовать мультизадачность, т.е. как программа будет вести себя если мы создадим несколько файберов. Рассмотрим 2 основных подхода, упомянутых ранее в постах про внутренности ОС:
🔹Кооперативная многозадачность - тип многозадачности, при котором фоновые задачи выполняются только во время простоя основного процесса и только в том случае, если на это получено разрешение основного процесса.
- Python (asyncio)
- JavaScript (async/await + Promise)
- Ruby (Fibers)
- Lua (coroutines)
- Java (virtual threads, JDK 21+)
- C++ (coroutines)
🔹 Вытесняющая многозадачность – тип многозадачности, в котором присутствует планировщик, обеспечивающий переключение между файберами. Каждый получает свой квант времени, в рамках которого делает полезную работу.
Реализована во всех языках в которых потоки исполнения являются реальными потоками OC и есть возможность создавать процессы.
- C/C++ (pthreads),
- Java без виртуальных потоков (java.lang.Thread)
- Node.JS (worker threads),
- Python(multiprocessing, multithreading)
- Ruby (fork, Thread)
Думаю, вы заметили, что одни и те же языки упоминаются в обоих абзацах. Что наводит на мысль что нет одного предпочтительного способа организации многозадачности, и что оба варианта можно и нужно комбинировать для достижения максимальной производительности.
Особенно внимательный читатель наверняка заметил, что нет упоминаний языка Go, и это не просто так. Дело в том что в Golang реализован гибридный подход к мультизаданчости и явно отнести язык в одну из категорий было бы неправильно.
На сегодня всё, в следующих постах будем изучать конкретные реализации многозадачности в языках программирования😇 Разберемся что там в Go, зачем нужен GIL, и попробуем разобраться как же правильно писать крутой конкурентый код зная всю ту базу о которой я рассказал ранее.
Спасибо за то что читали, до встречи!
Post #329
3.08K
- 👍 27
- 🔥 12
- ❤ 7