Linuxのカーネルの開発に関する世界観(シグナル)です。
自分の書いたブログ「わたしの名はフレイ」2020/06/26より。
プログラムを強制終了するためには、シグナルを使う。
シグナルにはいくらかの種類があるが、カーネルがシグナルを処理する際のデフォルトの挙動は、
| 処理方法 | 説明 |
|---|---|
| Ign | 無視する |
| Term | 強制終了 |
| Core | 強制終了してコアダンプを吐く |
| Stop | 一時停止する |
| Cont | 一時停止中だった場合に再開する |
の5種類。(@IT、Man page of SIGNALより)
シグナルは、たとえばSIGHUP, SIGINT, SIGQUITのように、SIG*という名前がついている。これらのシグナルに対して、TermやCoreやIgnといったデフォルトの動作が決まっている。
しかしながら、シグナルはプロセス側で処理を書き換えることができる。
これを「シグナルを捕捉する」あるいは「トラップする」と言う。
シグナルを上手くプロセス側で捕捉することで、標準で無視されるシグナルも活用できる。
(ふつうのLinuxプログラミング Linuxの仕組みから学べるgccプログラミングの王道を参考に執筆しました。)
基本的に、signal(2)あるいはsigaction(2)を使うことで、プロセスの中でシグナルを受けた場合の挙動を捕捉して変えられる。
シグナルは、デフォルトの処理をカーネル任せにするのではなく、自ら「シグナルを捕捉(トラップ)する」ことで処理を自由に変えられる。
signal()はUNIXの最初の時代から存在する、単純なシグナルの捕捉API。第一引数にシグナルの値(数値)、第二引数に実行する関数の関数ポインタを取る。
後日注記:signal()の使い方は以下が参考になります。
後日注記:signal()は単純だがさまざまな点から問題があり古いため、新しいプログラムであればsigaction()を使うべきだとされている。
2023.01.21編集
シグナルを送信する。名前は「kill」(殺す)だが実際には強制終了だけではなくさまざまなシグナルを送信できる。
後日注記:Linuxの主なシグナルには、
| シグナル | 説明 |
|---|---|
| SIGTERM (15) | プロセスの正常終了(デフォルト) |
| SIGKILL (9) | 強制終了(捕捉や無視はできない) |
| SIGINT (2) | キーボードからの割り込み、Ctrl+C |
| SIGHUP (1) | 設定の再読み込みとデーモンのリロード |
| SIGQUIT (3) | Ctrl+\で終了し、コアダンプを生成 |
| SIGSTOP (17/19) | プロセスの一時停止 |
| SIGCONT (18) | 停止したプロセスの再開 |
などがある。これらはkillコマンドを使ってシグナル名や番号からプロセスIDを指定して送り付けることができる。
kill -シグナル番号/名前 PID
以上はGoogleのAIを参考にしました。
2026.02.20編集
UNIXのシグナルは、ソフトウェア割り込みを実装した機構のひとつ。そもそもはハードウェアの非同期割り込みのための機構だったが、それをソフトウェアで実装した。
(シグナルの概念 | LinuxCを参考に執筆しました。)
シグナルについては、以下の書籍が参考になります。
また、シグナルのman pagesが以下にあります。詳しい仕様を知りたい方は以下を参照のこと。
UNIXコマンド(プロセス)も参照のこと。