マルチプロセスでシグナル処理

前々回の投稿で書いたこちらのプログラム http://d-nishiyama.hatenablog.com/entry/2013/06/29/170848 ですが、実行を停止しようと思って Ctrl+C を押してもなんと停止しない・・・!

正確には親プロセスは停止するのですが、子プロセスはそのまま動き続けてしまいます。 どうやらシグナル処理なるものをやらないといけないそうです。

適当にググってやり方を調べ、なんとか書いてみたのがこちら。

■parent.sh

#!/bin/sh

exit_parent() {
    echo "trapped."
    kill -TERM  -$$
    exit 1
}

trap "exit_parent" HUP INT QUIT TERM

sh child.sh 1 &
sh child.sh 2 &
sh child.sh 3 &
sh child.sh 4 &

wait

echo "終了"

■child.sh

#!/bin/sh

for i in `seq 1 100`;do
    echo プロセス ${1} の ${i} 回目の出力
    sleep 1
done

ポイントは

trap "exit_parent" HUP INT QUIT TERM

という行です。これは親プロセスに送られた HUP, INT, QUIT, TERM のシグナルをキャッチして 指定したコマンド(ここでは exit_parent)を実行します。

exit_parent は関数として定義されていて 子プロセスに終了コマンドを送信し、

kill -TERM  -$$

自分自身も exit 1 で終了します。(強制終了扱いなので exit の引数は1としました。)

$$ は親プロセスのPIDですが、これは親プロセスと、それから生まれた子プロセスが作る グループのグループIDでもあります。kill コマンドの引数にPIDを負値で渡してやると、 それはグループIDと解釈されるそうです。 なのでここでは親プロセスと、子プロセス全体にTERMシグナルが送信され、親プロセスの停止と同時に 子プロセスも停止させることができます。


参考:http://www.linuxmaster.jp/linux_skill/2005/10/035kill.html