Unixの親プロセスと子プロセスの関係について
はじめまして。
親プロセスが終了するとそのプロセスから呼ばれた
子プロセスも停止するという認識は正しいでしょうか?
というのも、あるシェルスクリプトを"kill -9"コマンドで強制終了させたのですが、そのシェルスクリプト内のコマンド(sleepコマンドです)は終了せずに残っていたので(psで確認しました)、??という感じでした。
さらにそのsleepコマンドの親プロセスが1(init?)になっていました。
色々とWEB上で調べてみたのですが、この動作について
の記述を見つけることができませんでした。
どなたかご存知でしたら是非ご教授下さい。よろしくお願いします。
投稿日時 - 2006-02-15 18:01:00
親プロセスが先に死ぬと子プロセスはinitプロセスの養子になるというのはunixの仕様です。
プロセスグループという概念があります。子プロセスは親プロセスのプロセスグループ番号を引き継ぎます。プロセスグループ番号はシステムコールで変更できます。変更した場合、自プロセスがプロセスグループリーダーとなって、親プロセスとは別グループになります。プロセスグループ番号は、通常はプロセスリーダーのプロセス番号です。
シェルからコマンドを起動した場合、通常は1パイプが1プロセスグループになります。
aa | bb ; cc
だと、aa と bb は同一プロセスグループ。ccは別プロセスグループ。
で、このプロセスグループ全体にシグナルを送ることが出来ます。システムコールだと、killpg(2)。コマンドだと、プロセスグループ100番にシグナルを送るとすると、kill --100 または kill -15 --100 で出来るのではないかと思います。
(やや自信なしですが、シェルでのパイプ実行中のctrl-CはプロセスグループへのSIGTERMだと思います)
プロセスグループ番号はpsコマンドで参照できます。psのオプションを調べてみてください。
別の方法として、ps の結果を解析してPPIDを調べ、プロセスの親子関係を調べ上げれば、自分が祖先になっている全プロセスをリストアップすることが出来るでしょう。それらに個別にシグナルを送る。
投稿日時 - 2006-02-20 00:30:50
このQ&Aは役に立ちましたか?
2人が「このQ&Aが役に立った」と投票しています
回答(4)
がるです。
そうですねぇ…ちと状況が見えきっていないのですが。
killallで-g(--process-group)オプションをつけるような感じではどうでしょうか?
投稿日時 - 2006-02-15 21:22:04
がるさん
度々すみません。
残念ながらAIXを使用しているため、がるさんが教えてくださった方法はできなそうです。(AIXのkill/killallコマンドのオプションが貧弱です)
やろうとしていた事は、だいたい以下のような感じです。
(1)以下のシェルスクリプトを実行
#!/usr/bin/bsh
vmstat 60 >> /hoge/log
・
・
・
(2)結果、psコマンドでは2つのプロセスが動いています。
-シェルスクリプトのプロセス(親)
-vmstat 60のプロセス(子)
(3)あらかじめファイルに保存しておいた親(シェルスクリプトの方)のPIDを読み込みkillすることで、上記2つのプロセスを終了させる。
上の例では子プロセスが1つしかない為、その子プロセスのPIDも別途保存しておいてkillするのが手っ取り早そうですが、killすべきプロセスが多い場合は、シェルスクリプトの記述が煩雑になってしまいそうだったので、うまく1つのkillコマンドで全関連プロセスを停止できれば、、と思った次第です。
なにかアドバイスが可能であれば是非お願いいたします。だめそうであれば諦めます。。
投稿日時 - 2006-02-15 22:10:30
がると申します。
んっと、親プロセスが死んだときに「子プロセスが停止する」とは限りません。というか、親プロセスのもう一つ親(なので、大抵は1のinitプロセス)に結び付けられるような状態になります(っていう挙動がMUSTだったかどうかははっきりしませんが、少なくともそういう実装系は存在します)。
ですので、通常のデーモンであれば、自分がkillされたタイミングで自分からforkした全子プロセスに対してkillシグナルを出すように設計されているもんだと思います。
投稿日時 - 2006-02-15 18:25:27
がるさん
お返事ありがとうございます。
結論としては、
”親プロセスが死んだときに子プロセスが停止する”というのは、意図的にそのように実装されたデーモンなど
だけであって、OSの通常のユーザープロセスに関しては当てはまらないということですね。
とすると、子シェルをたくさん呼び出している親シェルをkillすることで一括して関連プロセスを全て落とすということはできなそうですね。
投稿日時 - 2006-02-15 19:31:52