目の前に僕らの道がある

勉強会とか、技術的にはまったことのメモ

signalのメモ

signalとは外部のプロセスに対して通信するためのメッセージです。プロセスに定義されているシグナルハンドラがsignalを補足して定義に応じた処理を行います。
killコマンドを使って行うことが多いですかね。

signalの種類

man pageを引いてみるとPOSIX.1-1990で定義されているsignalは以下の通りのようです。

% LANG=C man 7 signal
       Signal     Value     Action   Comment
       ----------------------------------------------------------------------
       SIGHUP        1       Term    Hangup detected on controlling terminal
                                     or death of controlling process
       SIGINT        2       Term    Interrupt from keyboard
       SIGQUIT       3       Core    Quit from keyboard
       SIGILL        4       Core    Illegal Instruction
       SIGABRT       6       Core    Abort signal from abort(3)
       SIGFPE        8       Core    Floating point exception
       SIGKILL       9       Term    Kill signal
       SIGSEGV      11       Core    Invalid memory reference
       SIGPIPE      13       Term    Broken pipe: write to pipe with no
                                     readers
       SIGALRM      14       Term    Timer signal from alarm(2)
       SIGTERM      15       Term    Termination signal
       SIGUSR1   30,10,16    Term    User-defined signal 1
       SIGUSR2   31,12,17    Term    User-defined signal 2
       SIGCHLD   20,17,18    Ign     Child stopped or terminated
       SIGCONT   19,18,25    Cont    Continue if stopped
       SIGSTOP   17,19,23    Stop    Stop process
       SIGTSTP   18,20,24    Stop    Stop typed at tty
       SIGTTIN   21,21,26    Stop    tty input for background process
       SIGTTOU   22,22,27    Stop    tty output for background process

signal受信時のデフォルトの動作

signalを受信するとプロセスのシグナルハンドラが処理を行うのですが、定義されていない場合、デフォルトの動作を行います。

種類 動作
Term プロセスの終了
Core プロセスの終了とコアダンプの出力
Stop プロセスの一時停止
Ign 無視する
Cont プロセスの開始(停止していた時)

システムで使用できるsignalの種類

kill -lを打つと使用できるsignalを確認することができます。

% kill -l
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS

コマンドラインからsignalを送る

killコマンドを使うのが一般的です。-シグナル番号もしくは-シグナル名をオプションに指定します。

% kill -9    ${PID}
% kill -KILL ${PID}

Perlでシグナルハンドリング

%SIGにシグナルハンドラーを定義できます。

use strict;
use warnings;

{
    local $SIG{HUP} = sub {
        warn '握りつぶすよ';
    };

    local $SIG{INT} = sub {
        warn '1秒待って死ぬよ';
        sleep 1;
        die  'さようなら';
    };

    local $SIG{ALRM} = sub {
        warn 'アラームを受け取ったよ';
    };

    while (1) { }
}

SIGHUPとSIGALRMをいくら送ってもにぎりつぶされてしまいます。デフォルトの動作ではどちらもTermなのでシグナルハンドラーが定義できていることがわかります。

% perl signal2.pl &
[1] 26442
% kill -HUP 26442
握りつぶすよ at signal2.pl line 7.
% kill -HUP 26442
握りつぶすよ at signal2.pl line 7.
% kill -HUP 26442
握りつぶすよ at signal2.pl line 7.
% kill -ALRM 26442
アラームを受け取ったよ at signal2.pl line 17.
% kill -INT 26442
1秒待って死ぬよ at signal2.pl line 11.
さようなら at signal2.pl line 13.

[1]  + exit 255   perl signal2.pl
perl signal2.pl  117.54s user 0.02s system 98% cpu 1:59.16 total