シグナルは、ソフトウェアの割り込み機構で非同期処理の実装に利用されます。
#include <signal.h> void (*signal (int sig, void (*disp)(int)))(int); int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
シグナルは、ソフトウェアの割り込み機構で非同期処理の実装に利用されます。あるプロセスがシグナルを受信すると、そのプロセスが現在実行中の処理を一時中断し、そのシグナルに対応したシグナルハンドラを実行します。シグナルハンドラの処理が終了すると、中断していた処理を再開します。
シグナルハンドラとは、プロセスがシグナルを受信したときに実行する関数のことです。この関数の中で、生じたシグナルに対応する処理を記述します。
シグナルの発生は、プログラムや子プロセスなどから発生することが考えられ、また、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
プログラムの処理のはじめで、どのシグナルを拾って処理するか 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
#
signal(3), sigaction(2), kill(2)