После чтения о процессах легкого веса Erlang я был в значительной степени уверен, что они были "зелеными потоками". Пока я не считал, что существуют различия между зелеными потоками и процессами Erlang. Но я не получаю его.
Каковы фактические различия?
Зеленые потоки могут напрямую обмениваться памятью данных между собой (хотя синхронизация, конечно, необходима).
Эрланг использует не "зеленые потоки", а что-то более близкое к "зеленым процессам": процессы не делятся памятью данных напрямую, а "копируют" ее (т.е. имеют независимые копии исходных данных)
.Когда люди возражают против того, чтобы называть процессы Erlang «зелеными потоками», они не возражают против «зеленой» части, они возражают против «части».
Разница между потоки и процессы в основном то, что потоки имеют только свой собственный указатель инструкций, но совместно используют все остальное (особенно состояние, память, адресное пространство). Процессы OTOH полностью изолированы и ничего не разделяют.
Процессы Erlang ничего не разделяют, таким образом, они являются настоящими процессами. Однако обычно они реализуются «зеленым» способом. Так что технически это «зеленые процессы».
Я обычно называю их «зелеными потоками», когда я хочу подчеркнуть легкую реализацию , и называю их «процессами». когда я хочу подчеркнуть семантику «ничего не разделяемое» . Таким образом, мне не нужно объяснять, что я имею в виду под «зелеными процессами».
Это упрощение заходит слишком далеко, чтобы сказать, что процессы Эрланга не могут напрямую обмениваться памятью данных, и что они только копируют значения друг между другом. Это скорее описание того, как это может быть реализовано, и как можно притвориться, что это реализовано. По крайней мере, для всех целей, кроме проблем с производительностью.
Эрланг накладывает несколько семантических ограничений на то, что вы можете делать как программист. Например, значения неизменны, что означает, что вы не можете изменить их после того, как они построены. Тогда понимаешь, что нескольким процессам Эрланга было бы совершенно неплохо получить доступ к одному и тому же значению в памяти, так как ни один из них не может его изменить в любом случае. Тогда блокировки не нужны.
Заметные ситуации, когда это делается в Erlang/OTP:
erl -hybrid
, которая объединяет кучи процессов и кучи общих папок, заставляя процессы копировать значения из кучи процессов в кучи общих папок первыми при их использовании в сообщении. Я нашел эту тему о гибридных кучах, которая также объясняет некоторые проблемы с концепцией.Другой трюк, который можно сделать, это фактически мутировать значения, но сделать так, чтобы оно не было видно. Это является дополнительным объяснением того, что непреложные значения являются семантическим ограничением.
Вот несколько примеров, когда OTP/Erlang на самом деле будет мутировать значения:
Эти оптимизации идут под теорию, что "если дерево падает в лесу, и никого нет рядом, чтобы его услышать, действительно ли оно издает звук?". То есть, ссылки не должны были ускользнуть от объекта, который должен быть мутирован. Потому что тогда можно заметить, что он изменился.
И это действительно то, о чем говорит семантика Эрланга, вещи не должны меняться как побочный эффект того, что делает какой-то другой процесс. Мы бы назвали это общим состоянием , и нам это совсем не нравится.
Другое упрощение, которое заходит слишком далеко, это сказать, что у Эрланга нет никаких побочных эффектов. Но это еще один вопрос, если его когда-нибудь зададут.