Signals in Erlang
Here’s the translation of the Go signals example to Erlang, formatted for Hugo:
-module(signals).
-export([main/0]).
main() ->
% Erlang signal handling works by sending messages to the process
% We'll create a process to receive these notifications
SignalHandler = spawn(fun() -> signal_handler() end),
% Register the process to receive notifications of the specified signals
ok = os:set_signal(sigint, SignalHandler),
ok = os:set_signal(sigterm, SignalHandler),
% We could receive signals here in the main function, but let's see
% how this could also be done in a separate process, to demonstrate
% a more realistic scenario of graceful shutdown.
Done = make_ref(),
% This process executes a blocking receive for signals. When it gets
% one it'll print it out and then notify the program that it can finish.
spawn(fun() ->
receive
{os_signal, Signal} ->
io:format("~n~p~n", [Signal]),
SignalHandler ! {self(), Done}
end
end),
% The program will wait here until it gets the expected signal
% (as indicated by the process above sending a message) and then exit.
io:format("awaiting signal~n"),
receive
{_, Done} ->
io:format("exiting~n")
end.
signal_handler() ->
receive
{From, Ref} ->
From ! {self(), Ref};
_ ->
signal_handler()
end.
Erlang signal handling works differently from Go, but we can achieve similar functionality. Here’s how the Erlang version works:
We define a
main/0
function as the entry point of our program.Instead of channels, Erlang uses message passing between processes. We spawn a
signal_handler
process to handle signals.We use
os:set_signal/2
to register our signal handler process for SIGINT and SIGTERM signals.We spawn another process that waits for a signal message and then notifies the main process.
The main process waits for the notification before exiting.
When we run this program, it will block waiting for a signal. By pressing Ctrl+C (which the terminal shows as ^C), we can send a SIGINT signal, causing the program to print the signal and then exit.
$ erl -noshell -s signals main -s init stop
awaiting signal
^C
sigint
exiting
This example demonstrates how to handle signals in Erlang, providing a way for Erlang programs to gracefully respond to system signals like SIGINT or SIGTERM.