2017-02-10 14 views
4

waitForが使用されていない場合、JVMを強制終了しても子プロセスには影響しません。ここに例があります。waitForを使用している場合、JVMを強制終了すると子プロセスも終了するのはなぜですか?

bashスクリプト:

#!/usr/bin/env bash 
echo "Sleeping..." > 'log' 
sleep 30 
echo "Wake up" >> 'log' 

Javaコード:Java Code

public class Code { 
    public static void main(String[] args) throws Exception { 
    Process process = Runtime.getRuntime().exec("./child.sh"); 
    // process.waitFor(); 
    } 
} 

が発行され、JVMはすぐに終了します。そしてps -ef | grep 'child.sh' | grep -v grepショー:

jing  3535 2761 0 13:47 pts/15 00:00:00 bash ./child.sh 

は、その後30秒後に、私は現在のディレクトリにlogファイルの内容を確認してください。内容は次のとおりです。

Sleeping... 
Wake up 

そして上記のgrepコマンドは何も表示されません。今度はprocess.waitFor()をコメント解除し、Code.javaを再コンパイルします。 java Codeを実行した後、上記のgrepコマンドを使用して、child.sh子プロセスが実行されていることを確認します。次にCtrl-Cを発行し、JVMを終了します。上記のgrepコマンドを実行すると、何も表示されません。私はこの動作を説明していませんProcessのJavadocをチェックした

Sleeping... 

:ようとlogファイルの内容が残ります。次に、次のコードを使用して、forkexeclp、およびwaitpidシステムコールの動作を確認します。そしてそれは同じ振る舞いを示しています。

私はOracle JDK 1.8をUbuntu 14.04で使用しています。 uname -aが生成する:

Linux jinglin 3.13.0-108-generiC#155-Ubuntu SMP Wed Jan 11 16:58:52 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 

誰もがwaitForwaitpidのこの効果についての説明を与えることができますか?

Does Process.waitFor() make the process reliant on the java parent?は、MACプラットフォームで同様の問題を尋ねます。しかしそれは詳細が欠けている。だから私はここで私の環境のためにこの質問をする。

答えて

3

waitPid()には何も特別なことはありませんが、親プロセスをフォアグラウンドにしておくことは他にありません。


あなたはフォークと子供が終了するのを待ち場合は、このような(単純化)プロセスツリーがあります。

─┬= 1 init 
└─┬= 2 bash --login 
    └─┬= 3 java code 
    └─── 4 bash child.sh 

javaは、端末の前景プロセスであり、子供が中にありますそのプロセスグループ。

^Cを押すと、フォアグラウンドプロセスグループ全体が終了します


あなたがいない待機を行う場合は、最初にあなたのプロセスツリーは、上記のものと同じです。javaプロセスが終了し、子プロセスがプロセスツリーのルートにあるプロセスの子になります。

─┬= 1 init 
├──= 2 bash --login 
└─── 4 bash child.sh 

子プロセスの実行が終了し、正常終了します。


プロセスグループは、デフォルトのアクションが終了するされたSIGINTを受信します。ただし、別のシグナルハンドラをインストールすることもできます。

+0

本当ですか?制御端末は、関連する3つのプロセスすべてで同じであり、決して閉じません。 –

+0

真。しかし、どのようにそれらが終了するのですか? – Ingo

+0

カーネルは、端末内のセッションのフォアグラウンドプロセスグループにSIGINTを送信します。 –

関連する問題