シグナルとは?

ryichk
·
公開:2023/11/28

プロセスは基本的に一本の流れに沿ってひたすら実行し続ける。

シグナルは、プロセスの実行の流れを外部から強制的に変えるための仕組みである。

シグナルには複数の種類がある。

SIGINTはbashなどのシェルにおいて`Ctrl`+`c`と打つと送られるものである。

SIGINTを受け取ったプロセスは終了する。

しかし、SIGINTを受け取ったら必ず終了するわけではない。

プロセスは各シグナルにおけるシグナルハンドラという処理をあらかじめ登録しておける。

プロセス実行中にシグナルを受信すると処理を中断し、シグナルハンドラを実行し、終わったら元の処理を再開させる。

シグナルを無視する設定も可能。

シグナルハンドラを使えばSIGINTを送っても終了しないプログラムを作れる。

シグナルはbash以外からもkillコマンドによって送れる。

例えば、SIGINTを送りたければ`kill -INT <pid>`を実行する。

他にも以下のようなシグナルがある。

  • SIGCHLD:子プロセス終了時に親プロセスに送られる。

    このシグナルハンドナラの中でwait()系システムコールを実行するのが一般的。

  • SIGSTOP:プロセスの実行を一時的に停止する。

    bash上で`Ctrl`+`z`を押すと、bashはこのシグナルを送り、実行中プロセスを停止できる。

  • SIGCONT:SIGSTOPなどにより停止したプロセスを再開する。

シグナルの一覧は`man 7 signal`コマンドで見られる。

絶対殺すSIGKILLシグナルと絶対死なないプロセス

SIGKILLを受け取ったプロセスは必ず終了させられる。

シグナルハンドラによる挙動の変更はできない。

稀にSIGKILLでも終了しない凶悪なプロセスが存在する。

このプロセスは何らかの理由により長時間シグナルを受け付けないuninterruptible sleepという特別な状態になっている。

この状態のプロセスは、`ps aux`のSTATフィールドの1文字目がDになる。

よくあるのがディスクI/Oに時間がかかっている時。その他にはカーネルに何らかの問題が起きていることもある。いずれにせよユーザからはどうにもできないことが多い。

参照

[試して理解]Linuxのしくみ ―実験と図解で学ぶOS、仮想マシン、コンテナの基礎知識【増補改訂版】

@ryichk
wanna be a good hacker.