🎓 A1Learner
🔍
0 of 46 lessons completed

Elixir Exit Signals

An exit signal is a notice that asks a process to end, sent with Process.exit. It is not a plain message, so it is not read from the mailbox like one.

Kill ends the target

A kill signal ends a worker that is waiting for a message.

worker = spawn(fn -> receive do :stop -> :ok end end)
Process.exit(worker, :kill)
:timer.sleep(100)
IO.puts(Process.alive?(worker))

Normal is ignored

A normal signal leaves a waiting worker alive.

worker = spawn(fn -> receive do :stop -> :ok end end)
Process.exit(worker, :normal)
:timer.sleep(100)
IO.puts(Process.alive?(worker))
send(worker, :stop)

A plain message ends nothing

A plain kill message just waits in the mailbox, and the worker stays alive.

worker = spawn(fn -> receive do :stop -> :ok end end)
send(worker, :kill)
:timer.sleep(100)
IO.puts(Process.alive?(worker))
{:message_queue_len, len} = Process.info(worker, :message_queue_len)
IO.puts(len)
send(worker, :stop)

Example

worker = spawn(fn -> receive do :stop -> :ok end end)
other = spawn(fn -> receive do :stop -> :ok end end)
send(worker, :kill)
Process.exit(other, :kill)
:timer.sleep(100)
IO.puts(Process.alive?(worker))
IO.puts(Process.alive?(other))
send(worker, :stop)

Key points

  • Signal: Process.exit sends an exit signal to a chosen process.
  • Kill: The reason :kill always ends the target process.
  • Normal: The reason :normal is ignored by a process that is not set to catch exits.
  • Message: A plain message waits in the mailbox and ends nothing by itself.
  • Difference: An exit signal is handled by the runtime, while a plain message waits in the mailbox to be read.

In this example, one worker gets a plain kill message and the other gets a kill signal. The first worker stays alive, and the second worker ends.

Note

The reason :kill cannot be caught, so it ends even a process set to catch exits.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Which reason always ends the target when sent with Process.exit?