Как устроена многопоточность в разных языках
Если хотите сделать доклад для конференции — сравните подходы к чему-нибудь в разных языках. Такой доклад можно прочитать на конференциях всех упомянутых языков. Устроить турне по городам, почувствовать себя звездой🥰
Однажды так и сделаю, но пока просто напишу пост, как разные языки работают с потоками. Рассмотрим Java, Python, JavaScript и Go.
Немного базы:
▫️ Если у процессора 8 ядер, в каждый момент времени выполняется максимум 8 задач
▫️ Задачи выполняются потоками операционной системы (ОС). Планировщик ОС распределяет процессорное время между потоками ОС
▫️ Процесс — это запущенная программа. У каждого процесса своя память и ресурсы. Другие процессы не имеют к ним доступа.
▫️Внутри процессов есть потоки. Каждый поток выполняет свою задачу. Потоки могут обмениваться данными через общую память процесса.
✨ Python и JavaScript ✨
В каждом процессе (программе) используется один поток операционной системы.
Потоки в этих языках - это способ логического разделения задач. Например, запрос 1 выполняется в потоке Т1, запрос 2 — в потоке Т2. У каждой задачи своя область видимости и локальные переменные. Один поток ОС переключается между такими "потоками", и так создаётся иллюзия одновременного выполнения.
Один экземпляр сервиса нагружает только одно ядро процессора. Чтобы задействовать 8 ядер, запускают 8 экземпляров сервиса (процессов) + балансировщик.
✅ Нет многопоточных проблем, простой код
💔 Сложная и сильно связанная инфраструктура. Самих сервисов больше. Плюс у процессов нет общей памяти, поэтому обмен данными происходит через БД и очереди
✨ Java (традиционная модель) ✨
Потоки в джаве соотносятся с потоками ОС в отношении 1 к 1. Каждый экземпляр Thread жёстко связан с одним потоком в ОС. Планировщик ОС распределяет процессорное время. Если ядер 8, в каждый момент времени параллельно работают максимум 8 задач.
✅ Простая инфраструктура
✅ Общая память между потоками, обмениваться данными проще и быстрее
✅ Шикарная библиотека java.util.concurrent
💔 Дополнительные сложности: гонки, дедлоки, проблемы с видимостью и атомарностью. Многопоточный код сложно тестировать и дебажить
💔 Число потоков и задач в работе ограничивается ОС
Последний пункт для многих систем является серьёзной проблемой. Иногда сервер не может взять больше задач, даже если процессор не загружен полностью. Есть обходные пути типа реактивного программирования или корутин, но сейчас не об этом.
✨ Go и Java с виртуальными потоками ✨
Потоки соотносятся с потоками ОС как многие ко многим. Распределением потоков по ядрам ОС занимается сам процесс (JVM или Go runtime)
✅ Нет ограничений на количество потоков, а значит и на количество задач в работе
✅ Более простой код, не нужно экономить на потоках
💔 Многопоточные проблемы остаются
Что тут важно:
Говорят, что язык программирования не влияет на общую архитектуру. Квадратик микросервиса на схеме может быть написан на чем угодно. Это не совсем так. Синтаксис языка и правда не важен, а вот модель многопоточности напрямую влияет и на архитектуру, и на инфраструктуру.
Теорию рассказала, в следующем посте покажу конкретный пример🔥
Post #639
8.4K
- 🔥 144
- 👍 38
- ❤ 29
- 👎 10