модуль Signal
Многие операционные системы позволяют отправлять сигналы работающим процессам. Некоторые сигналы имеют определённое действие на процесс, тогда как другие можно перехватывать на уровне кода и обрабатывать. Например, ваш процесс может перехватывать сигнал USR1 и использовать его для включения и выключения отладки, а TERM — для инициирования контролируемого завершения работы.
pid = fork do
Signal.trap("USR1") do
$debug = !$debug
puts "Debug now: #$debug"
end
Signal.trap("TERM") do
puts "Terminating..."
shutdown()
end
# . . . do some work . . .
end
Process.detach(pid)
# Controlling program:
Process.kill("USR1", pid)
# ...
Process.kill("USR1", pid)
# ...
Process.kill("TERM", pid)
выводит:
Debug now: true Debug now: false Terminating...
Список доступных имён сигналов и их интерпретация зависят от системы. Семантика доставки Signal также может различаться в разных системах; в частности, доставка сигналов не всегда может быть надёжной.
Открытые методы класса
static VALUE
sig_list(VALUE _)
{
VALUE h = rb_hash_new();
const struct signals *sigs;
FOREACH_SIGNAL(sigs, 0) {
rb_hash_aset(h, rb_fstring_cstr(sigs->signm), INT2FIX(sigs->signo));
}
return h;
} Возвращает список имён сигналов, сопоставленных соответствующим номерам сигналов в системе.
Signal.list #=> {"EXIT"=>0, "HUP"=>1, "INT"=>2, "QUIT"=>3, "ILL"=>4, "TRAP"=>5, "IOT"=>6, "ABRT"=>6, "FPE"=>8, "KILL"=>9, "BUS"=>7, "SEGV"=>11, "SYS"=>31, "PIPE"=>13, "ALRM"=>14, "TERM"=>15, "URG"=>23, "STOP"=>19, "TSTP"=>20, "CONT"=>18, "CHLD"=>17, "CLD"=>17, "TTIN"=>21, "TTOU"=>22, "IO"=>29, "XCPU"=>24, "XFSZ"=>25, "VTALRM"=>26, "PROF"=>27, "WINCH"=>28, "USR1"=>10, "USR2"=>12, "PWR"=>30, "POLL"=>29}
static VALUE
sig_signame(VALUE recv, VALUE signo)
{
const char *signame = signo2signm(NUM2INT(signo));
if (!signame) return Qnil;
return rb_str_new_cstr(signame);
} Преобразует номер сигнала в его имя. Возвращает nil, если signo — недопустимый номер сигнала.
Signal.trap("INT") { |signo| puts Signal.signame(signo) }
Process.kill("INT", 0)
выводит:
INT
static VALUE
sig_trap(int argc, VALUE *argv, VALUE _)
{
int sig;
sighandler_t func;
VALUE cmd;
rb_check_arity(argc, 1, 2);
sig = trap_signm(argv[0]);
if (reserved_signal_p(sig)) {
const char *name = signo2signm(sig);
if (name)
rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
else
rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
}
if (argc == 1) {
cmd = rb_block_proc();
func = sighandler;
}
else {
cmd = argv[1];
func = trap_handler(&cmd, sig);
}
if (rb_obj_is_proc(cmd) &&
!rb_ractor_main_p() && !rb_ractor_shareable_p(cmd)) {
cmd = rb_proc_isolate(cmd);
}
return trap(sig, func, cmd);
} Задаёт обработчик сигналов. Возвращает предыдущий обработчик для указанного сигнала.
Аргумент signal — это имя сигнала (строка или символ, например SIGALRM или SIGUSR1) либо целочисленный номер сигнала. Если signal — строка или символ, начальные символы SIG можно опустить.
Аргумент command или переданный блок задаёт код, который будет выполнен при поступлении сигнала.
Аргумент command также может быть строкой или символом со следующими специальными значениями:
-
IGNORE,SIG_IGN: сигнал будет проигнорирован. -
DEFAULT,SIG_DFL: будет вызван обработчик Ruby по умолчанию. -
EXIT: процесс будет завершён сигналом. -
SYSTEM_DEFAULT: будет вызван обработчик операционной системы по умолчанию.
Специальное имя сигнала EXIT или номер сигнала ноль вызовет обработчик непосредственно перед завершением программы:
Signal.trap(0, proc { puts "Terminating: #{$$}" })
Signal.trap("CLD") { puts "Child died" }
fork && Process.wait
Вывод:
Terminating: 27461 Child died Terminating: 27460
Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.