2015-03-13 1 views
6

Я рассматриваю решение проблемы с использованием эликсира, главным образом из-за способности порождать большое количество процессов дешево.Может ли Elixir/Erlang скопировать процесс, включая его память?

В моем сценарии я хотел бы создать несколько «оригинальных» процессов, которые загружают определенные, неизменяемые данные в память, а затем делают копии этих процессов по мере необходимости. Копии будут использовать одни и те же базовые данные, но с ними будут выполняться разные задачи только для чтения; например, представьте, что в одном «оригинале» есть текст «Война и мир» в памяти, и каждая копия этого оригинала делает другой анализ в тексте.

Мои вопросы:

  • Можно скопировать существующий процесс, содержимое памяти и все, в эликсира/Эрланг VM?
  • Если да, то каждая копия потребляет столько же памяти, сколько и оригинал, или же они могут совместно использовать память, так как процессы Unix выполняют стратегию «копировать на запись»? (И в этом случае не будет никакой последующей операции записи.)
+0

Процессы не делят, а точнее, очень ограниченные конкретные типы данных. Большие двоичные файлы совместно используются. – rvirding

+0

Думаю, я, возможно, задал неправильный вопрос. Оглядываясь назад, я действительно хотел спросить: «Могу ли я загружать или создавать некоторые данные только для чтения, создавать множество процессов и использовать их все?» Ответ - да. Например, данные могут быть сохранены в атрибуте модуля или элементе модуля Elixir во время компиляции с использованием макроса, а порожденные процессы могут вызвать функцию или получить доступ к атрибуту во время выполнения. –

ответ

5
процесс

Erlang не имеет конкретный процесс данных отдельно от того, что хранится в переменных (и the process dictionary), так, чтобы сделать копию памяти о процесс, просто создайте новый процесс, передающий все соответствующие переменные в качестве аргументов функции.

В общем, память не разделяется между процессами; все скопировано. Исключениями являются таблицы ETS (хотя данные копируются из таблиц ETS, когда процессы читают его), и двоичные файлы размером более 64 байт. Если вы храните «Войну и мир» в двоичном формате и отправляете ее каждому рабочему процессу (или передаете его вместе, когда вы создаете эти рабочие процессы), тогда процессы будут разделять память, только копируя ее, если они захотят изменить двоичный файл , Дополнительную информацию см. В руководстве по эффективности Erlang chapter on binaries.

+1

Интересно. Фактические данные, которые я хочу использовать, будут больше похожими на словарь, где ключи - массивы чисел, а значения - массивы словарей. Будет ли возможность делиться и использовать через двоичный файл? (Извините за общие вопросы новичков, но я пытаюсь определить выполнимость, прежде чем погрузиться глубоко.) –

+2

Я бы начал с [таблиц ETS] (http://www.erlang.org/doc/man/ets.html). Хотя данные будут скопированы, когда вы их прочитаете из таблицы ETS, если вы смотрите только на часть этого процесса, рабочий процесс должен быть в состоянии идти в ногу с сборкой мусора. – legoscia

+2

Я тоже хотел бы пойти с ETS или просто отправить соответствующие данные другим процессам по требованию. Однако, если вы тестируете и это действительно проблема производительности, вы можете кодировать значение ключа как большой двоичный файл и каждый процесс извлекает из него информацию. IIRC, Крестен использует эту технику в своем приложении HanoiDB: https://github.com/krestenkrab/hanoidb –

6

Существует не встроенный способ копирования процессов. Самый простой способ сделать это - начать «оригинальный» процесс и «копии» и отправить все соответствующие данные в сообщениях в копии. Процессы не делят данные, поэтому нет более эффективного способа сделать это. Помещение данных в таблицы ETS частично помогает при совместном использовании, поскольку данные в таблицах ETS копируются в процесс, когда они используются, однако вам не нужно иметь все данные в куче процесса.

1

Вы считаете процессы Erlang/Elixir похожими на процессы Unix. Их совсем нет, мне действительно жаль, что у них не было другого имени, потому что они действительно не являются ни потоками, ни процессами в стандартном смысле Unix. Мне потребовалось некоторое время, чтобы обернуть голову вокруг различий.

Вы должны выбросить все свои предвзятые идеи о процессах, все они ошибаются. Eprocesses имеют следующие характеристики.

  • Они дешевые и быстрые. Используйте много, всегда есть больше.

  • У них нет ресурсов [1]. (Даже запись в stdout является сообщением другому Eprocess.)

  • IPC (или сообщения) очень быстрые с относительно низкими накладными расходами по сравнению со стандартным Unix IPC.

То, что я хотел бы попробовать в вашем случае, чтобы создать сервер, управляемый данные и иметь каждое сообщение анализ работника сервера для фрагментов данных, которые нужны.Совершенно приемлемо, чтобы Eprocess был более или менее менеджером общей памяти .

Для меня самый полезный способ думать об Eprocesses - это объекты с собственным потоком исполнения.

[1] Ну, есть таблица ETS, но лучше всего думать о них как об обмене ресурсами, пока вам не придется.

+0

Это процессы, а не процессы Unix. Существуют и другие системы, кроме Unix. :-) – rvirding

+0

На самом деле, я бы наверняка ответил на этот вопрос совсем по-другому после еще одного года обучения использованию BEAM. –

+0

Да Таблицы ETS на самом деле не разделены. Они больше похожи на доступность по всему миру, поскольку данные копируются между таблицами и вашим процессом при доступе к ним. Концептуально они выглядят как состояние процесса, но они реализуются по-разному. – rvirding

Смежные вопросы