• ベストアンサー

Unixの親プロセスと子プロセスの関係について

はじめまして。 親プロセスが終了するとそのプロセスから呼ばれた 子プロセスも停止するという認識は正しいでしょうか? というのも、あるシェルスクリプトを"kill -9"コマンドで強制終了させたのですが、そのシェルスクリプト内のコマンド(sleepコマンドです)は終了せずに残っていたので(psで確認しました)、??という感じでした。 さらにそのsleepコマンドの親プロセスが1(init?)になっていました。 色々とWEB上で調べてみたのですが、この動作について の記述を見つけることができませんでした。 どなたかご存知でしたら是非ご教授下さい。よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.3

親プロセスが先に死ぬと子プロセスは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を調べ、プロセスの親子関係を調べ上げれば、自分が祖先になっている全プロセスをリストアップすることが出来るでしょう。それらに個別にシグナルを送る。

その他の回答 (3)

  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.4

#3ちょっと修正。マイナスを二つ重ねるのは全く違う別の件と勘違いでした。 誤:kill -15 --100 正:kill -15 -100 誤:kill --100 正:kill -100 だと 100がプロセスグループ番号じゃなくてシグナル番号と見なされるので、kill -- -100 か kill - -100

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.2

がるです。 そうですねぇ…ちと状況が見えきっていないのですが。 killallで-g(--process-group)オプションをつけるような感じではどうでしょうか?

yunyun2
質問者

お礼

がるさん 度々すみません。 残念ながら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コマンドで全関連プロセスを停止できれば、、と思った次第です。 なにかアドバイスが可能であれば是非お願いいたします。だめそうであれば諦めます。。

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 んっと、親プロセスが死んだときに「子プロセスが停止する」とは限りません。というか、親プロセスのもう一つ親(なので、大抵は1のinitプロセス)に結び付けられるような状態になります(っていう挙動がMUSTだったかどうかははっきりしませんが、少なくともそういう実装系は存在します)。 ですので、通常のデーモンであれば、自分がkillされたタイミングで自分からforkした全子プロセスに対してkillシグナルを出すように設計されているもんだと思います。

yunyun2
質問者

お礼

がるさん お返事ありがとうございます。 結論としては、 ”親プロセスが死んだときに子プロセスが停止する”というのは、意図的にそのように実装されたデーモンなど だけであって、OSの通常のユーザープロセスに関しては当てはまらないということですね。 とすると、子シェルをたくさん呼び出している親シェルをkillすることで一括して関連プロセスを全て落とすということはできなそうですね。

関連するQ&A

  • logoutしたとき消えるプロセスは誰が消してるの?

    telnetなどでログインして プロセスを動作させて、ログアウトすると 動作させていたプロセスが消えるのですが、 誰がそのプロセスにシグナルを送っているのでしょうか? OSはsolarisを使っています。 シェルが子供を消しているのかと思ったのですが、 以下の動作をみるとそうでないみたいで・・ telnet .... $ $sh $sleep 10000 & 1234(←sleepのPID) $kill [shのPID] $ ps -eo pid,ppid,args | grep 1234 1234 1 sleep 1000 $exit telnet .... $ $ ps -eo pid,ppid,args | grep 1234 $ない

  • シェルで親プロセス終了時に子プロセスも終了させるには?

    シェルスクリプトを作っています. 親プロセス(AAA.sh)から子プロセス(BBB.sh)を呼び出した状態で,AAA.shをkillすると,BBB.shのプロセスが終了しないまま,残ってしまうため, http://oshiete1.goo.ne.jp/qa1968135.html を参考にkill -- -$$で同じプロセスグループのものが終了するように作ったのですが,BBB.shが呼び出される前にAAA.shをkillすると,プログラムが暴走してしまいます. どうすれば暴走せずに,親子ともども終了させることができるでしょうか??? *** AAA.sh *** #!/bin/sh func exit_AAA(){ kill -- -$$ exit 1 } trap "exit_AAA" HUP INT QUIT TERM echo "call BBB??(y/n)" read num ./BBB.sh *** BBB.sh *** #!/bin/sh echo "exit BBB?(y/n)>" read num

  • 子プロセスの状態を親プロセスに渡したい

    今、C言語を用いてシェルを作成していて、そこでcpコマンドを実現したいと思っています。その際、子プロセスを生成し、そこでgetcwdやchdirを使用してディレクトリの移動を行うのですが、子プロセスを終了させると親プロセスでは移動前のディレクトリに戻ってしまいます。 子プロセスでディレクトリを移動したときに,親プロセスでも移動された状態にするにはどうすればいいのでしょうか?それとも、この操作は親ディレクトリでしか行えないのでしょうか? できるだけ詳しく教えていただけるとありがたいです。回答よろしくお願いします。

  • 割り込み不可能?なプロセスを強制終了する方法

    Perlのスクリプトが、フリーズ(?)してしまいました。ps コマンドで状態をみると、D (割り込み不可能なスリープ状態 (通常 IO 中))になったままです。kill -KILL しても終了しません。 このような場合は、どうやって終了させればよいのでしょうか? また、何が原因で止まっているのかを調べる方法はありますでしょうか? 必要な情報があれば補足しますので、どなたか分かる方いましたら、お願いいたします。

  • プロセスの切り方

    質問です。 今会社(このカテゴリーをご覧になっていらっしゃる方でご存じの方が いると思いますが)でシェルを作成しているのですが、 時たまとんでもないミスをして、シェルが止まらなくなるときがあります。 その時即座に、ps-efでプロセス番号を割り出してkillしているのですが、 以前にミスったと思われるプロセスが残っていて困っています。 (実行時間が0:00となっているので、素人認識で大丈夫だと 思っているのですが、気になるのでkillで切ろうとすると所有者ではありません と言われてしまいます) どうすれば、こういったプロセスが切れるのかお教え下さい。

  • javaのプロセス起動について

    UNIXで例えば以下のようなコマンドでjavaのプロセスを停止するとします。 ps -eo pid,comm | awk '$2=="java" {print "kill -9" $1}' 逆にjavaのプロセスをコマンドで起動する方法はありますか?

  • UNIX(Linuxでも)のkillコマンドで、終了メッセージを抑止し

    UNIX(Linuxでも)のkillコマンドで、終了メッセージを抑止したい。 例えば、シェルの中で以下のようなコマンドがある場合に、 「○○が終了しました」とメッセージが出力されてしまいます。 抑止方法があれば教えてください。 kill xxx > /dev/null 2>&1 ※xxxはプロセスID よろしくお願いします。

  • シェルのプロセスを止めて再度同じシェルを動かすことは可能でしょうか?

    cronでシェルを定期的に動かし、前日に既に動いている自分のプロセスを止めて新たに動かすということをシェルの中でやりたいのですが、プロセスをPSで検索すると以前のプロセスと新たに動いたプロセスの両方をkillしてしまい実現できません。 何かよい方法があれば教えてください。 よろしくお願いします。

  • [Unix初心者]「ps|grep netscape|cut -f1|kill」がうまくいかない原因は?

    当方、大学の授業でSolarisを使うことになり その課題の1つとして以下のものが出されています 現在起動しているnetscapeを終了するにはどうしたらよいか、 手順を述べよ この問題自体は簡単で、 psコマンドでnetscapeのプロセスIDを調べ、 その調べた番号をkillすれば良い・・・ つまり psで 1000 (何だかわかってないけど何かしら) netscape とあったら kill 1000とすればいいのはわかっているのですが (おそらくこれが解答と思われます) 簡単な応用として 「起動しているnetscapeは1つとは限らず、  かつハイブを利用すべきだ」 を行ってみようと思い psでリストを表示したら先ほどの(分からない部分)が出てきています TAがこそこそ言っていたcutコマンドの存在を知り netscapeの「プロセスIDだけのリスト」にするために ps|grep netscape|cut -f1 と打ってみたのですが どうもプロセスIDのみになっていない様子。 解決へのヒントをください。 (たしかtcshシェルとかいっていた気が)

  • XPで、プロセスをKILLするDOSからのコマンドは。

    WindowsXPです。 Ctr+Alt+Del で、タスクマネージャを起動してプロセスのところを見ると、いらないプロセスがあるので、これを終了させる際、今は、このタスクマネージャでプロセスを選択して、プロセス終了をしています。 これをMSDOSのプロンプトから、コマンドで実行できませんか。 たとえば、 Kill "イメージ名" などのように。 (これは適当に書いたので、このコマンドは間違っていますが) KILLしたいプロセスが複数あるので、バッチファイルにしてまとめてKILLしたいのです。 よろしくお願いします。