модуль 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 если номер сигнала является некорректным.
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–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.