シグナル

プロセスに対して非同期イベントを通知する手段として、Linuxはシグナルと呼ばれる手段を用意している。

プロセスが例外を発生したとき、Linuxカーネルはシグナルに変換してプロセスに通知する。また、カーネル内である事象が発生したことを通知するためにLinuxカーネルがシグナルを生成することもある。(pipe,ttyなどで良く利用される)。また、プロセスがkillシステムコールにより明示的にシグナルを生成することも可能である。

プロセスに対してシグナルを送った(send_sig関数)とき、即対象となるプロセスが削除されたり、そのプロセスが登録したシグナルハンドラが起動されるわけではない。シグナル送信側はシグナルを通知するのみ*1であり、シグナル受信処理は全て対象プロセスのコンテキスト上で処理される(do_signal関数)。

シグナルの生成は、例外発生(0番地アクセスなど)やpipe/ttyの状態変更などによりLinuxカーネルが自動的に行うこともあるし、ユーザプロセスがkillシステムコールにより明示的に行うことも可能である。シグナル送信対象プロセスが待ちに入っている場合は、強制起床(wake_up_process)することもある。

プロセスはシグナル受信のチェックをシステムコール出口/例外ハンドラ出口/割り込みハンドラでチェックされる(ソフト割り込みのチェック箇所とほぼ同じ)。もしシグナルを受信していた場合は、シグナル受信処理(do_signal)を開始する。シグナル受信処理(do_signal)では、条件によりプロセスを終了させたり、ユーザシグナルハンドラの実行の準備を行う。ユーザシグナルハンドラの実行のための実装方式に関しては、下図と以下の関数説明を参照して欲しい。どのようなタイミングでシグナルが発生しても(下図signal A B)、シグナルをハンドリングする手順は同じである。

img11.gif

 

(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST
1


  1. *1killシステムコールが完了してもは相手のプロセスがその時点で終了したことは保証できない。そのあたりの動作を勘違いしたコードを良く見かける