Erlang язык не раскрывает темы, он дает вам процессы Erlang.Эти процессы планируются средой исполнения Erlang эффективно на потоки ОС, которые обычно отображаются на ядра ЦП.Они легкие (менее 4 КБ занимаемой памяти на 32-битной виртуальной машине, включая начальную кучу) и планируются с упреждением, так что блокировка или большое использование ЦП в любом из них не лишает любой другой процесс значительной доли ЦП.время.
Так что не бойтесь порождать процесс для обработки каждого из запросов, которые вы хотите обслуживать в вашей системе - это хороший начальный дизайн, который обычно обеспечивает хорошую пропускную способность за счет параллелизма и имеет тенденцию масштабироваться до большего количества ядер./ cpus / node легче.
Дополнительным преимуществом является то, что код в каждом процессе может быть написан простым процедурным способом:
%% Ask a server to perform a request and await the response from the worker.
request(Server, R) ->
Server ! {new_request, R, self()},
receive {response, Response} -> Response end.
%% Create a server.
start() ->
spawn(?MODULE, server, []).
%% The server code
server() ->
receive
{new_request, R, Sender} ->
%% Spawn a process to handle this request
spawn(?MODULE, process_request, [R, Sender]),
server()
end.
%% The worker code
process_request(R, Sender) ->
A = do_io(),
B = do_cpu_bound_thing(A),
C = do_io(C),
Sender ! {response, C}. % Return the response to the sender
%% Process shuts down cleanly here as there's nothing more to do.
Здесь мы имеем два вида процессаодин центральный серверный процесс, который принимает новые запросы, и любое количество рабочих процессов, которые фактически выполняют эту работу.Ошибки в отдельных запросах не влияют на процесс сервера или другие рабочие процессы, отдельные рабочие процессы могут выполняться с различной скоростью в зависимости от ввода-вывода и ресурсов ЦП.
Отсюда легко добавить контроль рабочих процессов, чтобы мы моглиперезапустите отдельные запросы, которые не выполняются, распределенная обработка на нескольких машинах, добавив аргумент 'Node' к вызову spawn, чтобы создать рабочих, тайм-ауты, чтобы клиенты, выполняющие запросы, не блокировались навсегда, если сервер перегружен или рабочий процесс завершился неудачей, и т.д.on.
Вы не можете получить параллелизм, на который способен вышеуказанный код, используя несколько обработчиков внутри процесса gen_event.Код gen_event будет более сложным для чтения, и вам придется самостоятельно чередовать запросы, а не позволять среде выполнения делать это за вас.
tl; dr: накладные расходы настолько малы, а другие преимущества таковызамечательно, что вы обычно (почти всегда) порождаете процесс, а не пытаетесь делать несколько вещей одновременно в процессе gen_event.