Erlang (and Elixir) Process Primitives

parent = self
:io.format("parent pid ~p~n", [parent])
child_pid = spawn(fn ->
:io.format("child process ~p~n", [self])

:timer.sleep 5_000 # sleep for 5 seconds

:io.format("Child done ~p~n", [self])
send parent, {self, :dead}
end)
receive do
msg -> IO.inspect msg
end

Understanding Erlang Processes

Erlang LWP’s are best understood by diagrams. Here’s one to get started:

proc_a = spawn(fn ->
:io.format("hello from proc A")
:io.format("Proc A is now going to wait for a message")
receive do
msg ->
IO.puts "proc A received message"
IO.inspect msg
end

IO.puts "Proc A is now ending"
end)
proc_b = spawn(fn ->
:io.format("hello from proc B")
:io.format("Proc Bis now going to wait for a message")
receive do
msg ->
IO.puts "proc Breceived message"
IO.inspect msg
end

IO.puts "Proc B is now ending"
end)

Process Communication

We would now like to do the following:

Linking Processes

We often have cases where we would like to create one or more processes whose existence depends on the existence of others.

proc_a = spawn(fn ->
:io.format("proc A: ~p~n", [self])
Process.register self, :proc_a
proc_b = spawn_link(fn ->
:io.format("proc B: ~p~n", [self])
Process.register self, :proc_b
receive do
end
end)
:io.format("proc A spawn_linked B at: ~p~n", [proc_b]) receive do
end
end)
:timer.sleep 1_000
IO.puts "killing proc B"
proc_b_pid = Process.whereis :proc_b
Process.exit proc_b_pid, :kill
:timer.sleep 100
IO.puts("Proc A: alive? #{Process.alive?(proc_a)}")
receive do
end

Monitoring Processes

While link'ing processes is great, there are often times when we don’t want both processes to die, if one of them dies. Instead, we want to create one directional link’s where if one of the processes dies the other get’s notified but does NOT die.

proc_a_pid = spawn_link(fn ->
IO.puts "hello from A"
Process.register self, :proc_a
{mon, proc_b_pid} = spawn_monitor(fn ->
IO.puts "hello from B"
:io.format("procB pid: ~p~n", [self])
Process.register self, :proc_b
receive do
end
end)
receive do
msg ->
IO.puts "proc A received msg"
IO.inspect msg
end
receive do
end
end)
:timer.sleep 500
proc_b_pid = Process.whereis :proc_b
Process.exit proc_b_pid, :kill
:timer.sleep 100
proc_a_alive = Process.alive? proc_a_pid
IO.puts "Proc A alive?: #{proc_a_alive}"
{mon, proc_b_pid} = spawn_monitor(fn ->
{:DOWN, #Reference<0.4279228456.2173435907.188346>, :process, #PID<0.143.0>,
:killed}

Summary

With a rudimentary understanding of these primitives:

  • spawn
  • send
  • receive
  • spawn_link
  • spawn_monitor

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store