gen_event:start_link().

{enter,into,a,scalable,world}.

Erlang Processes and Message Passing

A colleague of mine who is very motivated to learn Erlang asked me what are Erlang messages and how to create and use them ?

Let me explain it:

Erlang has been designed for massive concurrency, so Erlang processes are light-weight with a very small memory footprint (in the example bellow a child/0 process costs 2656 bytes on a multi-core 64-bit computer), fast to create and terminate and the scheduling overhead is low. In Erlang, processes shares nothing and exchange data through messages. You can create millions of processes inside the Erlang VM because the Erlang VM will not create millions of threads but it will assign each process to a process scheduler, for example if your computer has 8 processor cores, Erlang will create at least 8 process schedulers (in fact one operating system thread per processor core plus some I/O threads).

message.erl link
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
%% 1> c(message).
%% 2> Pid = spawn(message,child,[]).
%% 3> Pid ! hello.

-module(message).
-export([child/0]).

child() ->
    receive
        hello ->
            io:format("Hello man !~n", []),
            child();
        fuck ->
            io:format("You're a genuine asshole man !~n", []),
            child();
        who_are_u ->
            io:format("My unique process identifier is ~w~n", [self()]),
            child();
        stop ->
            true
    end.

Let try it:

$ erl
Erlang R16A (erts-5.10) [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V5.10  (abort with ^G)
1> P = spawn(message,child,[]).
<0.35.0>
2> processes().
[<0.0.0>,<0.3.0>,<0.6.0>,<0.7.0>,<0.9.0>,<0.10.0>,<0.11.0>,
 <0.12.0>,<0.13.0>,<0.14.0>,<0.15.0>,<0.16.0>,<0.18.0>,
 <0.19.0>,<0.20.0>,<0.21.0>,<0.22.0>,<0.23.0>,<0.24.0>,
 <0.25.0>,<0.26.0>,<0.27.0>,<0.28.0>,<0.29.0>,<0.33.0>,
 <0.35.0>]
3> P ! hello.
Hello man !
hello
4> P ! fuck.
You're a genuine asshole man !
fuck
5> P ! who_are_u.
My unique process identifier is <0.35.0>
who_are_u
6> {_,Size} = process_info(P, memory).
{memory,2656}
7> P ! stop.
stop
8> processes().
[<0.0.0>,<0.3.0>,<0.6.0>,<0.7.0>,<0.9.0>,<0.10.0>,<0.11.0>,
 <0.12.0>,<0.13.0>,<0.14.0>,<0.15.0>,<0.16.0>,<0.18.0>,
 <0.19.0>,<0.20.0>,<0.21.0>,<0.22.0>,<0.23.0>,<0.24.0>,
 <0.25.0>,<0.26.0>,<0.27.0>,<0.28.0>,<0.29.0>,<0.33.0>]
9> P ! hello.
hello

As you can see, I created a new process and assigned it to the P variable, its PID was <0.35.0> and it answered to all messages I sent to it (pattern matching of messages received in process mailbox). As I told, it costs 2656 bytes and when I sent the atom stop the process died. As result it is no longer shown via erlang:processes/0 and there is no answer to the last message I sent to its PID.