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?