こんにちわ。
20代の頃、システム開発の仕事をしていました。
特にパソコンをベースとしたプログラム開発の仕事をしたかったのですが、仕事なのでオフコンやUNIXでのシステム開発もいくつかやりました。
制御システムの開発がけっこう多かったので、マルチプロセス、マルチタスクのプログラミングもけっこうありました。
特にUNIXのシステムコールであるプロセス間通信のお世話によくなりました。

そのプロセス間通信の1つにシグナルというのがあります。
今回は、シグナルの話です。
シグナルって割り込みのこと?
シグナルとは、UNIXやUNIX系のOSなどで実装されているプロセス間通信のひとつです。
プロセス間あるいはスレッド間で非同期イベントの発生を伝える機能で、シグナルが送信されるとOSは対象のプロセスの正常な処理の流れに割り込みをかけます。
そして、割り込まれたプロセスが事前ににシグナルハンドラを登録しておけば、シグナルを受けた時に、その割り込みルーチンを実行することができます。
というわけで、シグナルとは割り込み処理のことだと言えます。
このシグナルの機能はある意味、大変便利というだけでなく一種のプログラミングモデルも提供しています。
シグナル機能そのものは主としてOSとアプリケーションのやりとりに使われますが、それはアプリケーション同士の通信にも必要であれば使うことができます。
もともとこの「シグナル」の機能は、ハードウェア・プログラミングから来ているそうです。
いわゆる「ハードウェア割り込み」の制御から生まれました。
CPUには割り込みを発生させるピンがありますが、それのことですね。
CPUが割り込み信号ピンの状態変化を検知し、割り込み制御ロジックを動かす、そんなふるまいをソフトウェアの世界にもちこんでいるわけです。
そして、その処理が終わると、途中で放棄された処理は何事もなかったかのようにそれまでの処理が継続されるという感じです。
シグナルは難しい
ですがこのシグナル、何らかの理由で今やっている処理に割り込むことができるので、使い勝手がいいのですが、その反面、様々な問題を起こしやすいので、実際には使いどころが難しい機能とも言えるんですよね。
たとえば、シグナルはキーボードからCtrl+Cを押したときに発生しますが、そのシグナルはその時、フォアグラウンドで実行中のプロセスへ送信され、プログラムの実行を中断します。
そういった、特別な状況で主に使用される機能です。
また、特定の任意シグナルを任意のプロセスへ送信する場合は、killコマンドというのを使います。
killコマンドは、プロセスIDで指定されたプロセスに対して、シグナル名、あるいはシグナル番号で指定されたシグナルを送信するコマンドです。
名前からして物騒ですね。(笑)
C言語で実装する場合もkillというシステムコールを使います。
そして、シグナルには次のようなものがあります。(一部のみ記載。)
シグナル
——————————————————–
SIGHUP 制御端末のハングアップ検出)
SIGINT キーボードからの割り込み)
SIGKILL Kill シグナル)
SIGALRM タイマーシグナル)
SIGUSR1 ユーザ定義シグナル 1
SIGUSR2 ユーザ定義シグナル 2
SIGCHLD 子プロセスの一時停止 (stop) または終了
ユーザーがアプリで使用するなら、SIGUSR1、SIGUSR2あたりを使用することになります。
C言語から処理を定義する場合は、システムコールのsigactionを使います。
昔は、signalというシステムコールを使っていたのですが、UNIX のバージョンにより動作が異なるようで、今はsigactionを使用するそうです。
このシステムコールでプログラムは特定のシグナルを受け取った時に、どのような処理を割り込みで実行するかを定義することができます。
なお、シグナルはプロセスが実行するとき、機械語命令の単位でプロセスの実行に割り込むので、メモリ空間に作業用のデータがある恐れもあります。
そのため、シグナルハンドラから安全に呼び出せる関数は限られます。
また、同じ理由でerrnoにも注意が必要です。
このように一般的なプログラミングの中では機械語、アセンブラレベルに近い配慮が必要ですので、普段は使わないと思いますが、どうしてもという時にシグナルを使うことで課題が解消されることがありますよ。
最後までおつきあい、ありがとうございました。
コメント