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);
}