プロセスにシグナルを送信する
kill
は指定のプロセスにシグナルを送信します。
SIGNAL には、シグナル名を文字列として、または、シグナル番号を数値として指定します。
LIST にはプロセス ID またはプロセスグループ ID を指定します。
複数のプロセス ID をリストとしてでまとめて指定することも可能です。
kill
は、シグナルの送信に成功したプロセスまたはプロセスグループの数を返します。
my $cnt = kill 'KILL', $pid;
下表は、一般的に良く使われるシグナル名とその意味を示しています。
シグナル名 | 意味 |
---|---|
HUP | 制御しているプロセスがハングアップ |
ABRT | 中断命令 |
KILL | プロセス強制終了命令 |
TERM | プロセス終了命令(デフォルト) |
STOP | プロセス一時停止命令 |
CONT | プロセス再開命令 |
SIGNAL に指定できるシグナル名は、先頭に SIG
を加えたものでも構いません。
たとえば、HUP
も SIGHUP
も指定可能です。
SIGNAL にはシグナル番号も指定可能ですが、シグナル番号は OS によって異なる場合があるため、
その利用は推奨されません。シグナル名を使ってください。
次のサンプルコードは、無限ループで永久に終わらない子プロセスを生成しています。
親プロセスでは 5 秒のタイムアウトを設け、子プロセスを kill
で強制終了しています。
# 子プロセスをフォークする
my $pid = fork();
# 親プロセスのコード
if ($pid) {
eval {
# 5 秒のタイムアウトをセット
local $SIG{ALRM} = sub { die "TIMEOUT\n" };
alarm 5;
# 子プロセスが終了するのを待つ
waitpid( $pid, 0 );
alarm 0;
};
if ( $@ eq "TIMEOUT\n" ) {
print "子プロセスがタイムアウトしました。\n";
# 子プロセスを強制終了
kill 'KILL', $pid;
print "子プロセスを強制終了しました。\n";
}
}
# 子プロセスのコード
else {
# 無限ループ
while (1) {
sleep 1;
}
exit 0;
}
上記サンプルコードは処理の流れを説明することを優先しているため、
さまざまなエラーハンドリングを省略しています。
本来であれば、kill
の返り値が 1 であり、
かつ、その直後に、指定の pid のプロセスが本当に終了しているのかをチェックする必要があります。
なぜなら、kill
はシグナルを送るだけだからです。
たとえ KILL
シグナルを送信したとしても、指定プロセスの強制終了が保証されるわけではありません。
タイムアウトの枠組みについては、alarm
関数の解説を参照してください。