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)









