Signals in Elixir
Elixir provides mechanisms to handle Unix signals, allowing programs to gracefully respond to events like termination requests or interrupts. Here’s how to handle signals in Elixir using the :os.signal/2 function and message passing.
defmodule SignalHandler do
def start do
# Register the process to receive SIGINT and SIGTERM signals
:os.set_signal(:sigint, :handle)
:os.set_signal(:sigterm, :handle)
# Print a message indicating we're waiting for a signal
IO.puts("awaiting signal")
# Start the signal handling loop
handle_signals()
end
defp handle_signals do
receive do
{:os_signal, signal} ->
IO.puts("\n#{signal}")
IO.puts("exiting")
end
end
end
# Start the signal handler
SignalHandler.start()In Elixir, we use the :os.set_signal/2 function to register our process to receive specific signals. We’re interested in SIGINT (interrupt) and SIGTERM (termination) signals.
The handle_signals/0 function uses Elixir’s receive block to wait for signal messages. When a signal is received, it’s printed, and then the program exits.
Unlike Go, Elixir doesn’t use channels for signal handling. Instead, it uses Erlang’s built-in message passing system. The operating system sends signals as messages to the registered process.
When we run this program, it will block waiting for a signal. By typing Ctrl+C (which the terminal shows as ^C), we can send a SIGINT signal, causing the program to print the signal name and then exit.
$ elixir signals.exs
awaiting signal
^C
SIGINT
exitingIn this Elixir version, we’ve maintained the core functionality of the original Go program while adapting it to Elixir’s idioms and concurrency model. The program still waits for a signal and gracefully exits when one is received.
Comments powered by Disqus