シグナル

  1. シグナル概要
  2. シグナルの送信
  3. シグナルの発生
  4. シグナルの処理
  5. シグナルハンドラの例
  6. シグナル一覧

シグナル概要

UNIX は、非同期イベントをプロセスに通知するためにシグナルを使います。

例えば、ユーザが Cntl-C を端末から打つと、現在実行中のプロセスに対して、 SIGINT シグナルが送られます。 同様にプロセスが終了すると、その親に対して SIGCHLD シグナルが送られます。

シグナルは、ソフトウェア割り込みと呼ばれることもあります。

シグナルの送信

UNIX は多くのシグナルを定義しています(4.3BSD と SVR で 31)。 そのほとんどは特定の目的のために確保されていますが、 SIGUSR1 と SIGUSR2 の2つは、アプリケーションで自由に使えます。

プロセスは kill システムコールを使って他のプロセスに明示的にシグナルを送れます。

またカーネルは、ハードウェア例外のプロセスや、割り当て超過状態を、 プロセスに知らせるためにシグナルを生成します。

各シグナルはデフォルトの応答として、プロセスを終了させます。 幾つかのシグナルは、デフォルトでは無視されたり、プロセスを中断したりします。

シグナルが送られるのは、次の2つの場合です。

シグナルの発生

シグナルは、次の場合に発生します。

  1. kill システムコールを使って、プロセスにシグナルを送る。
  2. kill コマンドを使って、プロセスにシグナルを送る。
  3. 端末から入力する文字のうち、いくつかはカーネルからシグナルが送られます。
    Cntl-C/DEL は SIGINT シグナルを発生します。
    Cntl-Z は SIGTSTP シグナルを発生します。
    Cntl-\ は SIGQUIT シグナルを発生します。
  4. ある種のハードウェア状態に伴い、カーネルからシグナルが送られます。
    浮動小数点演算のエラーは SIGFPE シグナルを発生します。
    プロセスの自アドレス空間以外のアドレスの参照は SIGSEGV シグナルを発生します。
  5. ある種のソフトウェア状態に伴い、カーネルからシグナルが送られます。
    CPU 時間が制限を越えると SIGXCPU を、
    ファイル・サイズが制限を越えると SIGXFSZ シグナルを発生します。

シグナルの処理

シグナルを受け取ったプロセスは何をすればよいでしょうか?

  1. プロセスは、特定のシグナルを受け取った場合に呼び出す関数を用意できます。
    これをシグナルハンドラといい、起こった状況に対処します。
  2. プロセスは、SIGKILL/SIGSTOP 以外のすべてのシグナルを無視するよう設定できます。
  3. プロセスは、以下の表にある既定時の動作がおこるように選択できます。

シグナルハンドラの例

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <wait.h>
#include <sys/types.h>
#define SHORT_TIME 5
#define MAX_COUNT  5
#define SZ_DATE     28

char *mkdate();
int mvbyte(char *,char,int);

int count=0;

int main(int argc,char *argv[]) {
  void     sigcatch(),(*istat)();
  char     date[SZ_DATE];

  istat = sigset(SIGINT,sigcatch);
  for (;;) {
    printf("%s    If you enter CNTL.C %d times over, then exit.(count=%d)\n",
           mkdate(date,SZ_DATE),MAX_COUNT,count);
    sleep(SHORT_TIME);
  }
  exit(0);
}

void sigcatch(int sig) {
  printf("Signal %d caught.\n",sig);
  if (count >= MAX_COUNT)   exit(0);
  count ++;
  sigset(SIGINT,sigcatch);
}

/*---------------------------------------------------------
   Function : make current time string
   Return   : A(current time string)
   Format   : yy/mm/dd hh:mm:ss
              12345678901234567
  ---------------------------------------------------------*/
char *mkdate(char *yymmdd,int size) {
  time_t tloc;
  struct tm  *cur;

  if (size < SZ_DATE)   {
     mvbyte(yymmdd,' ',size);
  }
  else {
     time(&tloc);
     cur = localtime(&tloc);
     strftime(yymmdd,size,"%y/%m/%d %T",cur);
  }
  return yymmdd;
}

int mvbyte(char *to,char code,int size) {
  int  i;
  for (i=0; i<size; i++)  *to ++ = code;
}

実行結果 

ozzy-100 11:00am] sig
01/12/19 11:12:58    If you enter CNTL.C 5 times over, then exit.(count=0)
^CSignal 2 caught.
01/12/19 11:13:01    If you enter CNTL.C 5 times over, then exit.(count=1)
^CSignal 2 caught.
01/12/19 11:13:01    If you enter CNTL.C 5 times over, then exit.(count=2)
^CSignal 2 caught.
01/12/19 11:13:02    If you enter CNTL.C 5 times over, then exit.(count=3)
^CSignal 2 caught.
01/12/19 11:13:03    If you enter CNTL.C 5 times over, then exit.(count=4)
^CSignal 2 caught.
01/12/19 11:13:03    If you enter CNTL.C 5 times over, then exit.(count=5)
^CSignal 2 caught.

シグナル一覧

4.3BSD および SVR のシグナルは以下に示すとおりですが、 AIX や Linux などでは、多少の違いがあります。

solaris、HP-UX、AIXは /usr/include/sys/signal.h を、
Linux は /usr/include/asm/signal.h を参照ください。

また、シグナルの拡張情報として siginfo 構造体の si_code に、 シグナルを発生させた理由が設定されます。

名 前 既定時 イ  ベ  ン  ト  内  容 入力 終了値
SIGHUP 1 Exit クローズされた端末上で動いていたプロセスに送られる
129
SIGINT 2 Exit 割り込み文字が入力されると送られます CNTL.C 130
SIGQUIT 3 Core 中止文字が入力されると送られます CNTL.\ 131
SIGILL 4 Core 不正な命令を実行すると送られる

si_code理由
ILL_ILLOPC 1 illegal opcode
ILL_ILLOPN 2 illegal operand
ILL_ILLADR 3 illegal addressing mode
ILL_ILLTRP 4 illegal trap
ILL_PRVOPC 5 privileged opcode
ILL_PRVREG 6 privileged register
ILL_COPROC 7 co-processor error
ILL_BADSTK 8 internal stack error


132
SIGTRAP 5 Core トレース/ブレークポイント・トラップが発生すると送られる

si_code理由
TRAP_BRKPT 1 process breakpoint
TRAP_TRACE 2 process trace trap


133
SIGIOT
SIGABRT
6 Core ハードウェア例外が発生すると送られる
134
SIGEMT 7 Core エミュレーション・トラップが発生すると送られる
135
SIGFPE 8 Core 浮動小数演算例外が発生すると送られる

si_code理由
FPE_INTDIV 1 integer divide by zero
FPE_INTOVF 2 integer overflow
FPE_FLTDIV 3 floating point divide by zero
FPE_FLTOVF 4 floating point overflow
FPE_FLTUND 5 floating point underflow
FPE_FLTRES 6 floating point inexact result
FPE_FLTINV 7 invalid floating point operation
FPE_FLTSUB 8 subscript out of range


136
SIGKILL 9 Exit プロセスを強制終了するときに送られる
137
SIGBUS 10 Core バス・エラーなどハードウェア例外が発生した場合に送られる

si_code理由
BUS_ADRALN 1 invalid address alignment
BUS_ADRERR 2 non-existent physical address
BUS_OBJERR 3 object specific hardware error
BUS_XMEM 4 reservation instruction to I/O address


138
SIGSEGV 11 Core セグメント・エラー例外が発生した場合に送られる

si_code理由
SEGV_MAPERR 1 ddress not mapped to object
SEGV_ACCERR 2 invalid permissions for mapped object


139
SIGSYS 12 Core 不正システム・コールをすると送られる
140
SIGPIPE 13 Exit パイプが壊れた場合に送られる
141
SIGALRM 14 Exit alarm() システムコールでアラーム・クロックが満了すると送られる
142
SIGTERM 15 Exit ソフトウェア終了シグナル
143
SIGUSR1 16 Exit ユーザ・シグナル1
144
SIGUSR2 17 Exit ユーザ・シグナル2
145
SIGCHLD 18 Ignore 子プロセスが終了したとき親プロセスに送られる

si_code理由
CLD_EXITED 1 child has exited
CLD_KILLED 2 child was killed
CLD_DUMPED 3 child terminated abnormally
CLD_TRAPPED 4 traced child has trapped
CLD_STOPPED 5 child has stopped
CLD_CONTINUED 6 stopped child had continued


146
SIGPWR 19 Ignore 電源断/再始動したときに送られる
147
SIGWINCH 20 Ignore ウィンドウ・サイズを変更すると送られる
148
SIGURG 21 Ignore 帯域外データが発生したときに送られる
149
SIGIO
SIGPOLL
22 Ignore I/O 可能が可能になると送られる
ソケット入出力可能になると送られる

si_code理由
POLL_IN 1 data input available
POLL_OUT 2 output buffers available
POLL_MSG 3 input message available
POLL_ERR 4 I/O error
POLL_PRI 5 high priority input available
POLL_HUP 6 device disconnected


150
SIGSTOP 23 Stop このシグナルを受けるとプロセスは中断します
151
SIGTSTP 24 Stop このシグナルを受けるとプロセスは中断します CNTL.Z 152
SIGCONT 25 Ignore 中断中のプロセスが再開するとそのプロセスに送られる
153
SIGTTIN 26 Stop tty 入力が中断したときそのプロセスに送られる
154
SIGTTOU 27 Stop tty 出力が中断したときそのプロセスに送られる
155
SIGVTALRM 28 Exit 仮想タイマが満了したときそのプロセスに送られる
(setitimer(2)参照)

156
SIGPROF 29 Exit プロファイル・タイマが満了した場合に送られます
(setitimer(2)参照)

157
SIGXCPU 30 Core 利用できる CPU 時間が制限を越えた場合に送られます
(ulimit(1),setrlimit(2)参照)

158
SIGXFSZ 31 Core 利用できるファイル・サイズが制限を越えた場合に送られます
(ulimit(1),setrlimit(2)参照)

159
SIGWAITING 32 Ignore スレッド・ライブラリによって利用されるスレッド同期用シグナル
160
SIGLWP 33 Ignore スレッド・ライブラリによって利用される LWP 間シグナル
161
SIGFREEZE 34 Ignore チェックポイントでの実行中断
162
SIGTHAW 35 Ignore チェックポイントでの実行再開
163
SIGCANCEL 36 Ignore スレッド・ライブラリによって利用されるキャンセル・シグナル
164
SIGLOST 37 Ignore リソースの喪失
165
SIGRTMIN 38 Exit 優先度の最も高いリアルタイム・シグナル
166
SIGRTMAX 45 Exit 優先度の最も低いリアルタイム・シグナル
159
SIGMSG 27 Ignore X 環境で、デバイスからの入力イベントが発生した時に使用されます
155
SIGDANGER 33 Exit リソースが枯渇するとプロセスに送られる。例えば malloc() が失敗する等
-

青字は AIX での名前です。

【 関連項目 】

signal(5),termio(7I),getrlimit(2),siginfo(5),kill(2),kill(1),ulimit(1)

【 参考書 】

名      前 著  者 出版社
最前線 UNIX のカーネル Uresh Vahalia ピアソン出版
UNIX ネットワークプログラミング W.Richard Stevens トッパン