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
傳遞語意也可能因系統而異;特別是訊號傳遞可能並不總是可靠的。
公開類別方法
list → 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(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; }
signame(signo) → string or 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); }
trap( signal, command ) → obj 按一下以切換來源
trap( signal ) {| | block } → obj
指定訊號處理方式。第一個參數是訊號名稱(例如「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
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); }