Signal
module 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...
可用信号名称及其解释列表取决于系统。信号传递语义也可能因系统而异; 特别是信号传递可能并不总是可靠的。
公共类方法
列表→a_hash显示源
返回映射到相应底层信号编号的信号名称列表。
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_list(void)
{
VALUE h = rb_hash_new(
const struct signals *sigs;
for (sigs = siglist; sigs->signm; sigs++) {
rb_hash_aset(h, rb_fstring_cstr(sigs->signm), INT2FIX(sigs->signo)
}
return h;
}
signame(signo)→string或nil显示源文件
将信号编号转换为信号名称。如果signo是无效的信号编号,则返回nil
。
Signal.trap("INT") { |signo| puts Signal.signame(signo) }
Process.kill("INT", 0)
生产:
INT
static VALUE
sig_signame(VALUE recv, VALUE signo)
{
const char *signame = signo2signm(NUM2INT(signo)
if (!signame) return Qnil;
return rb_str_new_cstr(signame
}
陷阱(信号,命令)→obj显示源
trap( signal ) {| | block } → obj
指定处理信号。第一个参数是信号名称(诸如“SIGALRM”,“SIGUSR1”等的字符串)或信号编号。信号名称中可以省略字符“SIG”。该命令或块指定在信号产生时要运行的代码。如果该命令是字符串“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
static VALUE
sig_trap(int argc, VALUE *argv)
{
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 (OBJ_TAINTED(cmd)) {
rb_raise(rb_eSecurityError, "Insecure: tainted signal trap"
}
return trap(sig, func, cmd
}