Signals in Julia
Here’s the translation of the Go code to Julia, with explanations adapted for Julia:
Our program demonstrates how to handle signals in Julia. For example, we might want a server to gracefully shutdown when it receives a SIGTERM
, or a command-line tool to stop processing input if it receives a SIGINT
. Here’s how to handle signals in Julia.
using Base.Threads
# Julia signal notification works by sending signal values to a channel.
# We'll create a channel to receive these notifications.
sigs = Channel{Int32}(1)
# We use `Base.sigatomic_begin()` and `Base.sigatomic_end()` to ensure
# signal handling is atomic.
Base.sigatomic_begin()
signal_handler = (sig) -> put!(sigs, sig)
Base.sigatomic_end()
# Register the signal handler for SIGINT and SIGTERM
for sig in [SIGINT, SIGTERM]
ccall(:signal, Ptr{Cvoid}, (Cint, Ptr{Cvoid}), sig, @cfunction(signal_handler, Cvoid, (Cint,)))
end
# We could receive from `sigs` here in the main function, but let's see
# how this could also be done in a separate task, to demonstrate a more
# realistic scenario of graceful shutdown.
done = Channel{Bool}(1)
# This task executes a blocking receive for signals. When it gets one
# it'll print it out and then notify the program that it can finish.
@async begin
sig = take!(sigs)
println()
println("Received signal: $sig")
put!(done, true)
end
# The program will wait here until it gets the expected signal
# (as indicated by the task above sending a value on `done`) and then exit.
println("awaiting signal")
take!(done)
println("exiting")
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 number and then exit.
$ julia signals.jl
awaiting signal
^C
Received signal: 2
exiting
In this Julia version:
- We use a
Channel
instead of a Go channel to receive signals. - We create a signal handler function and register it using
ccall
and@cfunction
. - Instead of a goroutine, we use Julia’s
@async
macro to create a task for signal handling. - We use
take!
andput!
for channel operations instead of<-
.
The overall structure and functionality remain similar to the Go version, adapted to Julia’s syntax and conventions.