Unix / Java процесс останавливается при перемещении в фоновый режим

1063
Craig Otis

У нас есть процесс Java, который был создан с использованием Appassembler. Он работает нормально, если он запущен и работает на переднем плане:

[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
Нажмите Q, чтобы выйти ... звучит так, как будто вы пытаетесь создать фон для интерактивной программы клавиатуры, которая, конечно, не даст желаемых результатов, когда вы отодвинете ее на задний план. Foosh 9 лет назад 0
В главном потоке он останавливается в ожидании `Q`, но это единственное, чего он ждет. (Остальная часть программы не управляется с клавиатуры, это простой способ убить ее, если вы активно запускаете процесс.) Перед запросом `stdin`, она запускает несколько фоновых потоков, которые * должны * продолжать работать, нет? Craig Otis 9 лет назад 0
Да, они «должны» продолжать работать, что приводит меня к мысли, что они ждут чего-то от основного потока. Зачем беспокоиться о вводе «Q», если вы планируете запускать его как демон? Или, лучше, определите ваше приложение, чтобы оно принимало флаг «daemon» при инициализации, чтобы оно вообще не ожидало на клавиатуре, но вы все равно можете использовать его для тестирования. И логирование - ваш друг, особенно когда вы пытаетесь найти проблемы с синхронизацией потоков. Foosh 9 лет назад 0

1 ответ на вопрос

2
Craig Otis

Кажется, что фоновые задания, ожидающие ввода , в большинстве сред останавливаются .

Со страницы Википедии в Unix Job Control :

Фоновому процессу, который пытается прочитать или записать на свой управляющий терминал, отправляется сигнал 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(); } } } 

Похожие вопросы