シグナル

はじめに

第4章はじめに

シグナルは、プロセスが予測不可能なイベントに対する処理を実行するための通知として使用されます。シグナルは、プロセス自体の中から、または他プロセスなどの外部イベントから発生します。シグナルの多くは重大な通知であり、結果としてプロセスが終了します。ただし、プログラムの設計者が特定の終了シグナルを処理（破棄）することを決定した場合、終了が回避されることがあります。一方で無害のシグナルも多くあります。単なる参考情報か、他の種類のアクションを要求するものです。kill、killall、pkillを使用して、コマンドラインからシグナル（終了を引き起こすシグナルを含む）を送信することができます。


学習目標
この章の終わりまでに、次のことができるようになります。

シグナルとは何か、どのように使用されるかを説明できるようになります。
Linuxで利用可能なシグナルとシグナルの種類について説明できるようになります。
kill、killall、pkillを使用して、コマンド ラインからシグナルを送信できるようになります。


シグナル

シグナルとは？
シグナルはプロセス間通信（IPC）の最も古い方法の1つであり、非同期イベント（または例外）をプロセスに通知するために使用されます。

非同期とは、シグナルを受信するプロセスが以下であることを意味します。

イベントが発生することを予期していないこと。
イベントの受信を予期しているが、いつ発生するするかわからないこと。

たとえば、ユーザーが実行中のプログラムを終了することを決定した場合、カーネルを介してプロセスにシグナルを送信し、プロセスを中断して強制終了できます。

シグナルがプロセスに送信される経路は２つあります。

例外またはプログラミング エラーの結果として、カーネルからユーザー プロセスへ送信。
（システムコールを使用して）ユーザー プロセスからカーネルへ送信し、そしてカーネルからユーザー プロセスへ送信。シグナルを送信するプロセスと受信するプロセスを同じにすることができます。

シグナルは、同じユーザーが所有するプロセス間、またはスーパーユーザーが所有するプロセスから任意のプロセスにのみ、送信できます。

プロセスがシグナルを受信して行う処理は、プログラムに書かれた内容によって異なります。プログラムにコード化されている特定のアクションを実行して信号を処理することも、システムのデフォルトに従って応答することもできます。2つのシグナル（SIGKILL と SIGSTOP）は処理はせず、常にプログラムを終了します。


シグナルの種類
シグナルにはさまざまな種類があります。カーネルによって送信された特定のシグナルは、発生したイベント（または例外）の種類を表しています。一般に、シグナルは次の2つのことを処理するために使用されます。

ハードウェアによって検出された例外（不正なメモリ参照など）
環境によって生成された例外（ユーザーの端末からのプロセスの早期終了など）。

Linuxのシグナルのリストとその番号を表示するには、このスクリーンショットに示されているように、kill -l を実行します。

利用可能なシグナル

SIGRTMINから後のシグナルはリアルタイム シグナルと呼ばれ、比較的最近追加されました。これらには事前に定義された目的はなく、いくつかの重要な点で通常のシグナルとは異なります。キューに入れることができ、FIFO（First In First Out）の順序で処理されます。

シグナルの種類は、（カーネルから送信されたときに）シグナルが送信される原因となったイベントを示しています。ユーザーは、プロセスの1つに任意の種類のシグナルを明示的に送信できますが、シグナル番号やその種類が示す意味に関係なく、プロセスが望む任意の方法で処理できます。

man 7 signalを入力すると、より多くのドキュメントが表示されます。

表：x86プラットフォームで利用可能なシグナル

シグナル　値　デフォルトの動作　POSIXか？　	意味
SIGHUP　 1　終了　Yes　制御端末でハングアップが検出されたか、制御プロセスの終了
SIGINT 　2　 終了　 Yes　キーボードからの割り込み
SIGQUIT　 3　コア ダンプ　Yes　キーボードから終了
SIGILL 　4　コア ダンプ　Yes　不正な命令
SIGTRAP　 5　コア ダンプ　No　デバッグ用のトレース／ブレークポイント トラップ
SIGABTR
SIGIOT 　6　コア ダンプ　Yes　異常終了
SIGBUS　　 7	コア ダンプ	Yes	バス エラー
SIGFPE 　8　コア ダンプ　Yes　浮動小数点例外
SIGKILL 　9　 終了　Yes　Killシグナル（キャッチや無視はできません）
SIGUSR1 　10　終了　Yes　ユーザー定義シグナル1
SIGSEGV 　11　コア ダンプ　Yes　不正なメモリ参照の発生
SIGUSR2 　12　終了　Yes　ユーザー定義シグナル2
SIGPIPE　 13　終了　Yes　破損したパイプ：読み手のないパイプへの書き込み
SIGALRM 　14　終了　Yes　アラームからのタイマー シグナル
SIGTERM 　15　終了　Yes　プロセスの終了
SIGSTKFLT　 16　終了　No　数値演算コプロセッサでスタック フォルト
SIGCHLD　 17　無視　Yes　子プロセスが停止または終了
SIGCONT 　18　継続　Yes　プロセスが停止中の場合は実行再開
SIGSTOP　 19　停止　Yes　プロセスの停止（捉えたり無視することはできません）
SIGTSTP　 20　 停止　Yes 　端末より入力された停止
SIGTTIN 　21 　停止　 Yes　バックグランド プロセスの端末入力
SIGTTOU　 22 　停止　 Yes　バックグランド プロセスの端末出力
SIGURG　 23　無視　No　ソケットの緊急状態（4.2 BSD）
SIGXCPU　 24　コア ダンプ　Yes　CPU時間制限を超過（4.2 BSD）
SIGXFSZ 　25　コア ダンプ　Yes　ファイル サイズの制限を超過（4.2 BSD）
SIGVTALRM　 26　終了　Yes　仮想アラーム クロック（4.2 BSD）
SIGPROF 　27　終了　No　プロファイリング アラーム クロック（4.2 BSD）
SIGWINCH 　28　無視　No　ウィンドウ リサイズ シグナル（4.3 BSD、Sun）
SIGIO
SIGPOLL　 29　終了　No　 I/Oが可能（4.2 BSD）（System V）
SIGPWR 　30 　終了　 No 　電源喪失（System V）
SIGSYS
SIGUNUSED　 31　終了　No　不正なシステムコール未使用シグナル


kill
プロセスは、別のプロセスに直接シグナルを送信できません。システムコールを実行して、シグナルを送信するようカーネルに要求する必要があります。ユーザー（スーパーユーザーを含む）は、次のように kill を使用してコマンド ラインまたはスクリプトから他のプロセスにシグナルを送信できます。

$ kill 1991

$ kill -9 1991

$ kill -SIGKILL 1991

これにより、PID = 1991 のプロセスにシグナルを送信します。（最初の例のように）シグナル番号が指定されていない場合、デフォルトでは、処理可能な終了シグナルのSIGTERM(15) が送信されます。プログラムはすぐに終了するのではなく、何らかのアクションを実行したり、終了のための後処理をすることができます。このシグナルが無視される場合は、ユーザーは無視できない SIGKILL(9) を送信して強制的に終了させることができます。

killという名前は明らかに印象が悪い名称で、歴史的な理由で生き残っている誤った呼び名です。多くの場合、プロセスを殺す（終了させる）ために使用されますが、このコマンドの本当の機能はあらゆるシグナルをプロセスに送信することです。


killallとpkill
killallは指定された名前を持つすべてのプロセスを強制終了します。ユーザーが十分な特権を持つと想定しています。プロセスIDではなくコマンド名を使用し、次のように実行します。

$ killall bash

$ killall -9 bash

$ killall -SIGKILL bash

pkillは、選択対象の基準を指定してプロセスにシグナルを送信します。

$ pkill [-signal] [options] [pattern]

例えば、

$ pkill -u libby foobar

これは、libbyユーザーのfoobarという名前がつくプロセスをすべて強制終了します。

別の例として、

$ pkill -HUP rsyslogd

これは、rsyslogに構成ファイルを再読み込みさせます。


演習

演習 4.1: シグナルの優先順位と実行

🚩
以下のPDFドキュメントに埋め込まれた外部URLにアクセスする場合は、常に右クリックして新しいタブまたはウィンドウで開いてください。直接クリックしてURLを開こうとすると、コース ウィンドウ／タブが閉じます。

Exercise 4.1: Examining Signal Priorities and Execution

We give you aCprogram that includes a signal handler that can handle any signal.  The handler avoids making any systemcalls (such as those that might occur while doing I/O). This file can be extracted from your downloaded SOLUTIONS file as signals.c

signals.c

You will need to compile it and run it as in:

$ gcc -o signals signals.c
$ ./signals

When run, the program:
•  Does not send the signals SIGKILL or SIGSTOP, which can not be handled and will always terminate a program.
•  Stores the sequence of signals as they come in, and updates a counter array for each signal that indicates how manytimes the signal has been handled.
•  Begins by suspending processing of all signals and then installs a new set of signal handlers for all signals.
•  Sends every possible signal to itself multiple times and then unblocks signal handling and the queued up signal handlerswill be called.
•  Prints out statistics including:
–The total number of times each signal was received.
–The order in which the signals were received, noting each time the total number of times that signal had beenreceived up to that point.

Note the following:
•  If more than one of a given signal israisedwhile the process has blocked it, does the processreceiveit multiple times?Does the behavior ofreal timesignals differ from normal signals?
•  Are all signals received by the process, or are some handled before they reach it?
•  What order are the signals received in?

One signal,SIGCONT(18 onx86) may not get through; can you figure out why?

Please Note
On someLinuxdistributions signals 32 and 33 can not be blocked and will cause the program to fail.  Even though system header files indicate SIGRTMIN=32, the command kill -l indicates SIGRTMIN=34.
Note that POSIX says one should use signal names, not numbers, which are allowed to be completely implementation dependent.
You should generally avoid sending these signals.


知識チェック

「第4章 - シグナル」を完遂しました。おめでとうございます。このクイズに答えて、これまでに学んだ概念の理解度をチェックしてください。

クイズ開始

問題 4.1
kill、killall、pkill allは、プロセス名をパラメータとして指定できます。True or False?

A. True
B. False

問題 4.2
kill -9とkill -SIGKILLは、ターゲット プロセスにおいて同じ効果があります。True or False?

A. True
B. False


問題 4.3
引数を指定しない場合、killはデフォルトでSIGTERMシグナルを送信します。True or False?

A. True
B. False

問題 4.4
端末で実行中のプロセスでCtrl + Zを押すことと、kill -SIGTSTPを使用することは、同じ効果があります。True or False?

A. True
B. False


