IPC: シグナル
シグナルは、ソフトウェアの割り込み機構で非同期処理の実装に利用されます。
SYNOPSIS
#include <signal.h> void (*signal (int sig, void (*disp)(int)))(int); int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
DESCRIPTION
シグナルは、ソフトウェアの割り込み機構で非同期処理の実装に利用されます。あるプロセスがシグナルを受信すると、そのプロセスが現在実行中の処理を一時中断し、そのシグナルに対応したシグナルハンドラを実行します。シグナルハンドラの処理が終了すると、中断していた処理を再開します。
シグナルハンドラとは、プロセスがシグナルを受信したときに実行する関数のことです。この関数の中で、生じたシグナルに対応する処理を記述します。
シグナルの発生は、プログラムや子プロセスなどから発生することが考えられ、また、kill
コマンドにより発生させることが出来ます。kill
コマンドにシグナルのタイプを指定し、シグナルを送りたいプロセスのプロセスID を指定します。
# ps -ef | grep sample shin 1149 1147 0 18:43:56 ? 0:03 sample # kill -9 1149 # <Enter> [1]+ killed sample #
シグナルのタイプは以下の表のとおりです。(Solaris の場合)
シグナル名 | Value | 詳細 |
---|---|---|
SIGHUP | 1 | Hangup |
SIGINT | 2 | Interrupt |
SIGQUIT | 3 | Quit |
SIGILL | 4 | Illegal Instruction |
SIGTRAP | 5 | Trace or Breakpoint Trap |
SIGABRT | 6 | Abort |
SIGEMT | 7 | Emulation Trap |
SIGFPE | 8 | Arithmetic Exception |
SIGKILL | 9 | Killed |
SIGBUS | 10 | Bus Error |
SIGSEGV | 11 | Segmentation Fault |
SIGSYS | 12 | Bad System Call |
SIGPIPE | 13 | Broken Pipe |
SIGALRM | 14 | Alarm Clock |
SIGTERM | 15 | Terminated |
SIGUSR1 | 16 | User Signal 1 |
SIGUSR2 | 17 | User Signal 2 |
SIGCHLD | 18 | Child Status Changed |
SIGPWR | 19 | Power Fail or Restart |
SIGWINCH | 20 | Window Size Change |
SIGURG | 21 | Urgent Socket Condition |
SIGPOLL | 22 | Pollable Event |
SIGSTOP | 23 | Stopped (signal) |
SIGTSTP | 24 | Stopped (user) |
SIGCONT | 25 | Continued |
SIGTTIN | 26 | Stopped (tty input) |
SIGTTOU | 27 | Stopped (tty output) |
SIGVTALRM | 28 | Virtual Timer Expired |
SIGPROF | 29 | Profiling Timer Expired |
SIGXCPU | 30 | CPU time limit exceeded |
SIGXFSZ | 31 | File size limit exceeded |
SIGWAITING | 32 | Concurrency signal reserved by threads library |
SIGLWP | 33 | Inter-LWP signal reserved by threads library |
SIGFREEZE | 34 | Check point Freeze |
SIGTHAW | 35 | Check point Thaw |
SIGCANCEL | 36 | Cancellation signal reserved by threads library |
SIGXRES | 37 | Resource control exceeded |
SIGRTMIN | * | First real time signal |
(SIGRTMIN+1) | * | Second real time signal |
... | ||
(SIGRTMAX-1) | * | Second-to-last real time signal |
SIGRTMAX | * | Last real time signal |
SAMPLE
プログラムの処理のはじめで、どのシグナルを拾って処理するか signal()
関数を使って定義しています。また、シグナルハンドラとなる関数を最後に定義しています。
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <signal.h> void sigint_handler(int sig); int main(void) { char s[200]; if (signal(SIGINT, sigint_handler) == SIG_ERR) { perror("signal"); exit(1); } printf("Enter a string: "); if (gets(s) == NULL) { perror("gets"); } else { printf("You entered - \"%s\"\n", s); } return 0; } void sigint_handler(int sig) { printf("Got a signal -> SIGINT\n"); }
これをコンパイルし実行すると以下のようになります。はじめは普通にプログラムを実行しています。2回目は、途中で Ctrl-C をタイプしてプログラムを中断しています。Ctrl-C をタイプした時点で、シグナルハンドラが呼び出されていることが確認できます。
# gcc signal_sample.c -o signal_sample # ./signal_sample Enter a string: hello You entered - "hello" # # ./signal_sample Enter a string: ^CGot a signal -> SIGINT gets: Interrupted system call #
SEE ALSO
signal(3), sigaction(2), kill(2)