この記事は検証可能な参考文献や出典が全く示されていないか、不十分です。出典を追加して記事の信頼性向上にご協力ください。(このテンプレートの使い方)
出典検索?: "シグナル" Unix
シグナル(英: signal)とは、Unix系(POSIX標準に類似の)オペレーティングシステム (OS) における、限定的なプロセス間通信であり、プロセスに対し非同期でイベントの発生を伝える機構である。シグナルが送信された際、OSは宛先プロセスの正常な処理の流れに割り込む。どんな不可分でない処理の間でも割り込むことができる。受信プロセスが以前にシグナルハンドラを登録しておけば、シグナル受信時にそのルーチンが実行される。さもなくば、デフォルトのシグナル処理が行われる。(同様なものは他のTSSなどでも開発されてはいるが、UNIXのシグナルは)1970年ごろベル研究所でUNIXに実装された。後にPOSIXである程度は標準化されているが、標準化が諦められているような振舞などもいくつかあり、特に他の幾つかの要素(fork等)とマルチスレッドとシグナルが絡むと実装毎の対処にプログラミングが大変になることがある。プロセスはI/O待ちなど、カーネルの内部で処理がブロックしている場合などで割り込み不可状態になることがあり、その場合は如何なるシグナルを送っても無効になる。
POSIX準拠のシグナルにあっては、プロセスへシグナルが配送され、シグナルハンドラの実行を開始および終了する際、以下の挙動を保証している。
シグナルハンドラの実行開始時に、配送されたシグナルのマスク、プロセスがあらかじめ追加指定したシグナルのマスク、およびプロセスが指定したスタックがある場合はそれへの切替をすべてアトミックに実行する。すなわち、シグナルハンドラ実行の準備としてそれらの処理を行っている最中に別のシグナルが配送されても、少なくともシグナルハンドラの実行開始までは別シグナルの処理を行わない。
シグナルハンドラ実行開始後の挙動は、シグナルマスクの設定に依存する。
シグナルハンドラが実行を終了すると、実行開始に際して変更したシグナルマスクおよびスタックの変更をシグナル配送前の状態へ巻き戻す。シグナルハンドラ実行開始時と同じく、巻き戻しの処理もアトミックに行う。
これらの仕様は、配送されたシグナルがシグナルマスクの設定に従って確実にシグナルハンドラを起動し、かつ不用意なシグナルハンドラへの再入を防ぐことを目的としている。このため、上記を満たすシグナルの実装を「信頼できるシグナル」と呼ぶことがある。POSIX以前の実装では上記の挙動が一部欠落していたり、アトミックに実行されないため、シグナルハンドラが期待通りに実行されなかったり、シグナルハンドラへの再入設定のためプロセス側で繊細な追加処理が必要になるなどの問題がしばしば生じていた。 以下のような操作によりシグナルが送信される。
シグナル送信
ユーザーがあるプロセスの端末のキーを押下したとき、端末がシグナルを発生する。
CTRL+C(古いUNIXでは DEL キー)を押下すると、SIGINT を送信し、デフォルトではそのプロセスを終了させる。
CTRL+Z を押下すると、SIGTSTP を送信し、デフォルトではプロセスの実行を中断(一時停止)させる。
CTRL+\ を押下すると、SIGQUIT を送信し、デフォルトではプロセスを終了させコアダンプさせる。
(なお、これらのキーの組み合わせは stty
kill(2) システムコールを使うと、権限があれば指定したプロセス(群)に指定したシグナルを送信できる。同様に kill(1) コマンドでユーザーがプロセス(群)にシグナルを送信することもできる。また、raise(3) を使えばカレントプロセス(またはスレッド)に指定したシグナルを送信できる。
ゼロ除算 (SIGFPE)、セグメンテーション違反 (SIGSEGV) などの例外によってもシグナルが発生する。経験の浅いプログラマはポインタに不正アドレスを入れてしまい、SIGSEGVを発生させることが多い。これらはデフォルトではプログラムを終了させ、コアダンプを生じる。
カーネルはプロセスに何らかのイベントを通知するためにシグナルを発生させることができる。