модуль 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);
} Задаёт обработку сигналов. Первый параметр — имя сигнала (строка, например “SIGALRM”, “SIGUSR1” и т. д.) или номер сигнала. Префикс “SIG” можно опустить в имени сигнала. Команда или блок задаёт код, который будет выполнен при возникновении сигнала. Если команда — строка “IGNORE” или “SIG_IGN”, сигнал будет проигнорирован. Если команда — “DEFAULT” или “SIG_DFL”, будет вызван обработчик Ruby по умолчанию. Если команда — “EXIT”, выполнение скрипта будет завершено сигналом. Если команда — “SYSTEM_DEFAULT”, будет вызван обработчик операционной системы по умолчанию. В противном случае будет выполнена указанная команда или блок. Специальное имя сигнала “EXIT” или номер сигнала, равный нулю, приведёт к вызову обработчика непосредственно перед завершением программы. trap возвращает предыдущий обработчик указанного сигнала.
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.