Unix/Java プロセスはバックグラウンドに移動すると実行を停止します

Unix/Java プロセスはバックグラウンドに移動すると実行を停止します

Appassembler を使用して作成された Java プロセスがあります。フォアグラウンドで起動して実行されている限り、正常に動作します。

[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$ bin/ourapp
Starting in APP_HOME=/home/ec2-user/app_home
Press Q to quit

その後、アプリケーションにアクセスしてテストすることができます。しかし、バックグラウンドで起動すると、実行が停止するだけでなく、それを前面に出す:

[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$ bin/ourapp &
[1] 11661
Starting in APP_HOME=/home/ec2-user/app_home
Press Q to quit
                                                     ## Not accessible!
[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$  jobs
[1]+  Stopped                 bin/ourapp
[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$  bg %1
[1]+ bin/ourapp &                                    ## Still not accessible!
[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$  jobs
[1]+  Stopped                 bin/ourapp
[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$  fg %1
bin/ourapp                                           ## Now, it's accessible.

不適切に起動していますか? バックグラウンドであってもジョブを実行し続ける方法はありますか? これをデーモン プロセスとして起動してログアウトする必要がありますnohupが、フォアグラウンド プロセスのままにしない限り、正常に実行し続けることができないようです。これは実現可能ではありません。

答え1

バックグラウンドジョブが入力待ちになっているようです停止されるほとんどの環境で。

からUnix ジョブ制御に関する Wikipedia ページ:

制御端末からの読み取りまたは制御端末への書き込みを試みるバックグラウンド プロセスには、SIGTTIN (入力の場合) または SIGTTOU (出力の場合) 信号が送信されます。これらの信号は、デフォルトでプロセスを停止しますが、他の方法で処理される場合もあります。

そして、Unix の中級者向けページ:

バックグラウンドで実行されているジョブは、入力が必要な場合には停止します。バックグラウンド ジョブには入力を与えることができないため、必要なすべての入力が利用可能であることを確認してください。

解決策としてJava プロセスを更新して、入力を待つのではなく、メイン スレッドを無期限にスリープさせるオプションの引数を受け入れるようにしました。シグナルを適切に処理するシャットダウン フックがありますSIGTERM/SIGINT

        if (args.length >= 0 && StringUtils.equals(args[0], "daemon")) {
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

関連情報