Modul Signal
Viele Betriebssysteme erlauben das Senden von Signalen an laufende Prozesse. Einige Signale haben eine definierte Auswirkung auf den Prozess, während andere auf Codeebene abgefangen und behandelt werden können. Zum Beispiel kann Ihr Prozess das USR1-Signal abfangen und zum Umschalten des Debuggings verwenden, und TERM zur Einleitung einer kontrollierten Abschaltung verwenden.
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)
ergibt
Debug now: true Debug now: false Terminating...
Die Liste der verfügbaren Signalnamen und deren Interpretation ist systemspezifisch. Die Zustellungssemantik von Signal kann ebenfalls zwischen Systemen variieren; insbesondere kann die Signalzustellung nicht immer zuverlässig sein.
Öffentliche Klassenmethoden
Source
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;
}
Gibt eine Liste von Signalnamen zurück, die den entsprechenden zugrunde liegenden Signalnummern zugeordnet sind.
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}
Source
static VALUE
sig_signame(VALUE recv, VALUE signo)
{
const char *signame = signo2signm(NUM2INT(signo));
if (!signame) return Qnil;
return rb_str_new_cstr(signame);
}
Konvertiert eine Signalnummer in einen Signalnamen. Gibt nil zurück, wenn die Signalnummer eine ungültige Signalnummer ist.
Signal.trap("INT") { |signo| puts Signal.signame(signo) } Process.kill("INT", 0)
ergibt
INT
Source
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);
}
Legt die Behandlung von Signalen fest. Gibt den vorherigen Handler für das gegebene Signal zurück.
Das Argument signal ist ein Signalname (ein String oder Symbol wie SIGALRM oder SIGUSR1) oder eine Integer-Signalnummer. Wenn signal ein String oder Symbol ist, können die führenden Zeichen SIG weggelassen werden.
Das Argument command oder der bereitgestellte Block gibt den Code an, der ausgeführt werden soll, wenn das Signal ausgelöst wird.
Das Argument command kann auch ein String oder Symbol mit den folgenden Sonderwerten sein
-
IGNORE,SIG_IGN: Das Signal wird ignoriert. -
DEFAULT,SIG_DFL: Der Standard-Handler von Ruby wird aufgerufen. -
EXIT: Der Prozess wird durch das Signal beendet. -
SYSTEM_DEFAULT: Der Standard-Handler des Betriebssystems wird aufgerufen.
Der spezielle Signalname EXIT oder die Signalnummer Null wird kurz vor Programmbeendigung aufgerufen
Signal.trap(0, proc { puts "Terminating: #{$$}" }) Signal.trap("CLD") { puts "Child died" } fork && Process.wait
Ausgaben
Terminating: 27461 Child died Terminating: 27460