Шапка треада Erlang
erlang-kunОтличительные киллер-фичи языка:
- BEAM (Bjarne Erlang Abstract Machine) – виртуальная машина, поверх которой работает erlang. Внутри себя разворачивает полную поляну для нижеуказанных фич под названием ERTS (Erlang RunTime System).
- эффективное использование всех ресурсов CPU – первая по значению часть ERTS является мощный планировщик, который масимально эффективно использует нагрузку всего процессора. на каждое ядро процессора разворачивается отдельная очередь исполнения, планировщик же старается поддерживать эти очереди сбалансированными
- массовый параллелизм – подобно S-выражениям лиспа, компилятор распиливает код на атомарные функциональные блоки, каждый из которых исполняет какое то выражение(-я). зачем это нужно? а затем, что процессов исполнения программы может быть значительно больше, чем ядер в системе. даже на нищем одноядерном ARM erlang машина может исполнять до 10000 одновременно исполняющихся процессов. процессы, очевидно, не системные, а представляют собой после компиляции цепочки этих самых функциональных блоков. порождение и уничтожение процесса очень дешевая операция, по сравнению с тяжелыми системными тредами, что не ведет к задержкам в переключении контекста [читать больше: https://cyberleninka.ru/article/v/effektivnost-nitey-v-mnogoprotsessornyh-sistemah-s-obschey-pamyatyu]
- умеренная чистота ФП – в общем понимании erlang можно назвать чистым языком, поскольку функции в нем не несут сайд-эффектов в текущем процессе. поясню, почему такая оговорка. связано это с тем, что, в erlang есть ровным счетом одна "нечистая" операция, это операции send/receive, которые используются для коммуникации между процессами
- простая синхронизация – в erlang нет ни мьютексов, ни семафоров, ни каких-либо остальных традиционных примитивов для синхронизации параллельных программ. для синхронизации исполнения программы используется только механизм передачи сообщений между процессами.
- асинхронная передача сообщений – операция отправки сообщения send _не_ является блокирующей, поскольку отправляет сообщение не напрямую в соответствующую инструкцию receive, а в mailbox процесса. то есть, другими словами, в широком смысле процесс-отправитель отправляет сообщение и не ждет ответа. но операция receive является блокирующей.
- полная изоляция процессов – между процессами нет разделяемой памяти. только передача сообщений между процессами.
- коммуникационная прозрачность – поскольку процессы изолированы друг от друга и обмениваются друг с другом только сообщениями, то не составит труда запустить эти же самые процессы на разных машинах – механизм их работы не изменится
- поддержка распределенного кода – из всего вышеперечисленного следует очень простая фича – язык позволяет писать сразу же код, который поддается легкому распределению между машинами в кластере, поскольку на уровне кода абсолютно нет разницы между тем, где работают процессы, на одной ноде или на нескольких
отсюда у приложений на этом языке появляется множество очень полезных свойств:
- отказоустойчивость – в составе языка помимо ERTS имеется набор шаблонов OTP, который позволяет писать легкомасштабируемый и безопасный код. процессы можно объединять в т.н. supervision trees, так что при отключении какого-нибудь процесса, он будет перезапущен.
- прозрачность логики – программы пишутся в декларативном стиле, от чего количество ошибок программиста уменьшается
- горячая замена кода – поскольку некоторые программы являются системами реального времени с высоким уровнем доступности (High availability), то простой для таких систем крайне критичен. erlang поддерживает замену байткода программы БЕЗ остановки виртуальной машины. так и достигается пресловутый uptime = 99,99999999% of time
- виртуальная машина, подобно престарелому баобабу, уже обросла таким количеством оптимизаций, что при соблюдении гайдлайнов и хорошем понимании своих действий позволяет писать максимально производительные приложения…
- … кроме числовых операций. erlang явно создавался не для научных расчетов, поэтому все операции над числами крайне долгие.
поскольку язык существует уже достаточно давно, в ERTS вшито уже достаточно много возможностей по умолчанию, которые позволяют сокращать время разработки, как то:
- упрощение распределенного программирования
- ETS – нечистая хэш таблица. хранит данные в виде erlang-термов, что позволяет не заморачиваться с сериализацией/маршалингом
- mnesia – нереляционная СУБД реального времени (под капотом, это абстракция над сетью ETS). из коробки умеет в масштабируемость в кластере и распределенные транзакции. позволяет писать более-менее сложные запросы с помощью кортежей условий, которые очень похожи на LISP
- leec + yecc – готовые парсер и лексер
- HIPE – альтернативная виртуальная машина, работает еще быстрее BEAM
- NIF + Ports – интерфейс для встраивания C-функций на уровне ядра виртуальной машины
- etc
Язык становится очень важным в последние годы, так как на сегодняшний день тенденция роста мощности одного ядра << тенденции роста числа ядер на одном кристалле. количество доступных
Программисту ядер и тредов растет, а используют все равно 1 поток исполнения, что печально.
Как влиться в разработку?
1) установить erlang из пакетного менеджера / собрать самому
2) Learn Some Erlang For Great Good [http://learnyousomeerlang.com] + Erlang and OTP In Action
Я советую для разработки использовать Intellij Idea IDE + erlang plugin, а в качестве простенького менеджера проектов rebar3, чтобы попервой не трахаться с написанием правильных Makefile.
Еще есть связка из emacs + distel, но в свете последних версий erlang/OTP пакет distel оказался сломан и на последних версиях erlang не работает (ждем фикс).
В последние годы еще пробился к популярности язык, построенный поверх BEAM, который можно окрестить как "erlang для ленивых" – Elixir. по сути – erlang с ruby синтаксисом. на самом деле, можно начать с него погружение в erlang-среду, потому что всё вышеописанное действительно и для Elixir, но у него намного проще абстракции, да и комьюнити у него, как ни странно, более активное. но я бы не советовал, честно, на нем зацикливаться, потому что Elixir много вещей пересоздает заново, что не очень разумно + чтобы хорошо писать на elixir нужно все же хорошо познать erlang/OTP.