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
exiting

In 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