地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

シグナルについて

f:id:ryuichi1208:20190113230348j:plain

シグナルとは

シグナルは、UNIXLinuxで使用されるプロセス間通信の一つです。

プロセスにシグナルを送信すると、そのプロセスの正常処理に割り込んで、シグナル固有の処理(シグナルハンドラ) が実行される」プロセス側では、シグナルを受信した際の動作(シグナルハンドラ) を設定することや、シグナルをブロックすることも可能。

Linuxのシグナルとしては、受け取る側はプロセスです。 送る側はカーネルの場合もあります。 そして、やり取りするシグナルには種類があり、各シグナルに番号が振られていて 番号によって実施する処理が違います。ユーザー定義のシグナルも送ることが可能です。

シグナル番号

Linuxではコマンドの実行かカーネルソースを読むことでシグナル番号を知ることができます。

#### kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

こんな感じ

#define SIGHUP           1
#define SIGINT           2
#define SIGQUIT          3
#define SIGILL           4
#define SIGTRAP          5
#define SIGABRT          6
#define SIGIOT           6
#define SIGBUS           7
#define SIGFPE           8
#define SIGKILL          9
#define SIGUSR1         10
#define SIGSEGV         11
#define SIGUSR2         12
#define SIGPIPE         13
#define SIGALRM         14
#define SIGTERM         15
#define SIGSTKFLT       16
#define SIGCHLD         17
#define SIGCONT         18
#define SIGSTOP         19
#define SIGTSTP         20
#define SIGTTIN         21
#define SIGTTOU         22
#define SIGURG          23
#define SIGXCPU         24
#define SIGXFSZ         25
#define SIGVTALRM       26
#define SIGPROF         27
#define SIGWINCH        28
#define SIGIO           29
#define SIGPOLL         SIGIO
/*
#define SIGLOST         29
*/
#define SIGPWR          30
#define SIGSYS          31
#define SIGUNUSED       31

/* These should not be considered constants from userland.  */
#define SIGRTMIN        32
#ifndef SIGRTMAX
#define SIGRTMAX        _NSIG
#endif

シグナルを送るには

Cのシステムコールやライブラリ関数を実行します

  • raise(3) 呼び出したスレッドにシグナルを送る。

  • kill(2) 指定されたプロセスや、指定されたプロセスグループの全メンバー、 システムの全プロセスにシグナルを送る。

  • killpg(2) 指定されたプロセスグループの全メンバーにシグナルを送る。 pthread_kill(3) 呼び出し者と同じプロセス内の指定された POSIX スレッドにシグナルを送る。
  • tgkill(2) 指定されたプロセス内の指定されたスレッドにシグナルを送る (このシステムコールを使って pthread_kill(3) は実装されている)。
  • sigqueue(3) 指定されたプロセスに付属データとともにリアルタイムシグナルを送る。

シグナルの配送

シグナルが配送されると、プロセスの通常処理に割り込んで、シグナルハンドラが実行される。

シグナル種類ごとにデフォルトの動作が決められており、個別にシグナルハンドラを登録していなければ、そのデフォルトの動作がカーネルにより実行される。デフォルトの動作は以下の5つ。

  • プロセスを終了する
  • コアを出力し、プロセスを終了する
  • シグナルを無視する
  • 処理を一時停止する
  • 処理を再開する

シグナル安全関数

POSIX が「非同期シグナル安全」を保証している関数群

fstat() read() sysconf() | access()
getegid() rename() tcdrain() | alarm()
geteuid() rmdir() tcflow() | cfgetispeed()
getgid() setgid() tcflush() | cfgetospeed()
getgroups() setpgid() tcgetattr() | cfsetispeed()
getpgrp() setsid() tcgetpgrp() | cfsetospeed()
getpid() setuid() tcsendbreak() | chdir()
getppid() sigaction() tcsetattr() | chmod()
getuid() sigaddset() tcsetpgrp() | chown()
kill() sigdelset() time() | close()
link() sigemptyset() times() | creat()
lseek() sigfillset() umask() | dup2()
mkdir() sigismember() uname() | dup()
mkfifo() sigpending() unlink() | execle()
open() sigprocmask() utime() | execve()
pathconf() sigsuspend() wait() | fcntl()
pause() sleep() waitpid() | fork()
pipe() stat() write()