Processes & Message Passing
Processes are cheap (~2.6 KB initial memory, microseconds to spawn).
24.1 Spawning processes
Processes are cheap (~2.6 KB initial memory, microseconds to spawn). Default max is ~262,144 processes; raise with erl +P 10000000.
Pid = spawn(fun() -> io:format("Hello from ~p~n", [self()]) end),
Pid2 = spawn(my_module, my_function, [Arg1, Arg2]), % spawn(M, F, A)
Pid3 = spawn(Node, fun() -> ... end), % on another node
is_process_alive(Pid).24.2 Sending & receiving
Each process has a mailbox (FIFO queue).
receive scans for the first message matching any pattern (selective receive); non-matching messages stay in the mailbox.
after 0 checks the mailbox without blocking.
Message ordering is guaranteed between a pair of processes only.
Pid ! {self(), hello}, % send: asynchronous, never fails, returns the message
receive
{From, hello} ->
From ! {self(), world};
{From, Other} when is_atom(Other) ->
From ! {error, unknown};
stop ->
ok
after 5000 -> % timeout in ms (or infinity)
timeout
end.24.3 A stateful server process
This client/server pattern — API functions wrapping messages, a tail-recursive loop holding state — is what gen_server generalizes.
-module(counter).
-export([start/0, increment/1, get/1, stop/1]).
start() -> spawn(fun() -> loop(0) end).
increment(Pid) -> Pid ! increment, ok.
get(Pid) ->
Ref = make_ref(),
Pid ! {get, self(), Ref},
receive
{Ref, Value} -> Value
after 5000 -> error(timeout)
end.
stop(Pid) -> Pid ! stop, ok.
loop(Count) ->
receive
increment -> loop(Count + 1);
{get, From, Ref} -> From ! {Ref, Count}, loop(Count);
stop -> ok;
_Unknown -> loop(Count) % discard junk to avoid mailbox growth
end.24.4 Registered names
register(counter, Pid),
counter ! increment,
whereis(counter), % Pid | undefined
unregister(counter),
registered().24.5 Process information & flags
self(),
process_info(Pid),
process_info(Pid, [message_queue_len, memory, current_function, status]),
erlang:processes(),
process_flag(trap_exit, true),
process_flag(priority, high), % low | normal | high | max (use sparingly)
process_flag(message_queue_data, off_heap),
erlang:send_after(1000, self(), tick),
erlang:start_timer(1000, self(), tick),
erlang:cancel_timer(TRef),
timer:sleep(100), timer:apply_after(1000, M, F, A), timer:send_interval(1000, tick).24.6 Process dictionary
put/2, get/1, erase/1 — per-process mutable storage. Avoid in normal code (hidden state), but used by some libraries (e.g., rand seeds, logger metadata).