II-8-6. シグナルの利用

シグナルを利用して非同期プログラミングを実現する方法を説明する。シグナルの種類やシグナルの取り扱い方法、タイマー割り込みプログラムの作成方法、プログラムの強制停止とシグナルハンドラ等の概念について述べる。

【学習の要点】

* シグナルとは、プロセス間(またはカーネルからプロセス)で、予め定義されたイベントを送受信する仕組みである。

* プロセスは各シグナルを受信したときのデフォルトの動作を持っている。これを上書きするには、signalシステムコールを用いてハンドラ関数を登録する。ただし、プロセスを強制終了させるなどの一部のシグナルについてはこれを上書きすることはできない。

* singalをプロセス間で用いると、互いにプロセス間通信を行うことができる。

* alermシステムコールとpauseシステムコール、SIGALRMシグナルハンドラを組み合わせると、タイマー割り込みプログラムを作成することができる。

SIGHUP

Hangup

SIGSTKFLT

Stack fault

SIGINT

Interrupt

SIGCLD (SIGCHLD)

Child status has changed

SIGQUIT

Quit

SIGCONT

Continue

SIGILL

Illegal instruction

SIGSTOP

Stop, unblockable

SIGTRAP

Trace trap

SIGTSTP

Keyboard stop

SIGABRT

Abort

SIGTTIN

Background read from tty

SIGIOT

IOT trap

SIGTTOU

Background write to tty

SIGBUS

BUS error

SIGURG

Urgent condition on socket

SIGFPE

Floating-point execution

SIGXCPU

CPU limit exceeded

SIGKILL

Kill, unblockable

SIGXFSZ

File size limit exceeded

SIGUSR1

User-defined signal 1

SIGVTALRM

Virtual alarm clock

SIGSEGV

Segmentation violation

SIGPROF

Profiling alarm clock

SIGUSR2

User-defined signal 2

SIGWINCH

Window size change

SIGPIPE

Broken pipe

SIGPOLL (SIGIO)

Pollable event occurred

SIGALRM

Alarm clock

SIGPWR

Power failure restart

SIGTERM

Termination

SIGSYS

Bad system call

図II-8-6. signal.hに記載のあるシグナル

【解説】

1) シグナルの送受信

* シグナルは、あるプロセスに対して、カーネル、他のプロセス、自プロセス、あるいはユーザが特定のイベントを送信するソフトウェア割り込みである。

* プロセスに対して送信されたシグナルは、そのプロセスの用意するシグナルハンドラによって捕捉される。プロセスが明示的にシグナルハンドラを用意しない場合は、デフォルトのアクションが実行される。

* シグナルハンドラを用意することで、プロセスがシグナルに対するデフォルトのアクションを上書き、拒否、または無視することを可能にする。

* カーネルの送信する一部のシグナルは、シグナルハンドラによって捕捉できない。これらは、SIGSTOPとSIGKILL の2つのシグナルであり、プロセスの暴走時に強制的に終了させる手段を残すためである。

2) シグナルを使ったプログラミング

* プロセスがシグナルを捕捉するようにハンドラを用意するには、signalシステムコールを用いる。signalは、受け取るべきシグナルの種類を示す整数値と、ハンドラ関数へのポインタを取り、以前のハンドラ関数を返す。呼び出しに失敗するとSIG_ERRを返す。

* Linuxでは、ハンドラ関数ポインタとsignalシステムコールは、以下のように定義されている。

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

* このとき、ハンドラ関数handleは以下のようにしてsignalシステムコールに渡すことができる。

sighandler_t h = &handle;

signal(SIGBUS, h);

* POSIX.1 (IEEE Std 1003.1) 標準のシステムでは、signalよりも一般的なsigactionシステムコールを使うことができる。これらのシステムではsignalはsigactionを用いて実装されている。sigactionは、シグナルの生成とハンドラの呼び出しに関してより細かい制御が可能である。

* kill, killpgは、それぞれ他のプロセス、プロセスグループに対してシグナルを送信するのに使うシステムコールである。

3) シグナルを使ったプログラミングの用途

* シグナルはもともと、プロセス間通信を行なうために設計されたものではないが、固定的なイベントを送受信するだけである場合、その目的に使うことができる。

* 実装例として、シグナルSIGALRMの送信と、pauseシステムコール (POSIX.1システムではsigsuspendを使用可能) を組み合わせたタイマーアプリケーションが考えられる。

OSS Course Naviのコンテンツは IPA OSS モデルカリキュラムを基としています。