Der Unix / Java-Prozess wird nicht mehr ausgeführt, wenn er in den Hintergrund verschoben wird

1183
Craig Otis

Wir haben einen Java-Prozess, der mit Appassembler erstellt wurde. Es läuft einwandfrei, solange es gestartet und im Vordergrund ausgeführt wird:

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

Wir können dann die Anwendung erfolgreich aufrufen und testen. Wenn wir es jedoch im Hintergrund starten, hört es nicht nur auf zu laufen, sondern wir können es scheinbar nicht wiederbeleben, ohne es in den Vordergrund zu bringen :

[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. 

Beginne ich es nicht richtig? Gibt es eine Möglichkeit, den Job am Laufen zu halten, obwohl er im Hintergrund läuft? Ich muss dies als Daemon-Prozess mit nohupund dann abmelden, aber es scheint nicht, dass er erfolgreich ausgeführt wird, es sei denn, es bleibt der Vordergrundprozess, was nicht machbar ist.

1
Zum Beenden drücken Sie Q ... Sieht so aus, als würden Sie versuchen, ein interaktives Keyboard-Programm als Hintergrund zu verwenden, das natürlich nicht die gewünschten Ergebnisse liefert, wenn Sie es in den Hintergrund schieben. Foosh vor 9 Jahren 0
Im Haupt-Thread wartet es auf 'Q', aber das ist das einzige, worauf es wartet. (Der Rest des Programms ist nicht tastaturgesteuert. Dies ist nur eine einfache Möglichkeit, ihn zu beenden, wenn Sie den Prozess aktiv ausführen.) Bevor Sie 'stdin' abfragen, werden einige Hintergrund-Threads gestartet, die * weiterhin * ausgeführt werden sollten. Nein? Craig Otis vor 9 Jahren 0
Ja, sie "sollten" weiterlaufen, was mich glauben lässt, dass sie auf den Haupt-Thread warten. Warum sollten Sie sich die Eingabe "Q" machen, wenn Sie dies als Dämon ausführen möchten? Oder besser, definieren Sie Ihre App so, dass sie ein "Daemon" -Flag akzeptiert, wenn sie initialisiert wird, sodass sie nicht auf der Tastatur wartet, Sie können sie jedoch weiterhin zu Testzwecken verwenden. Die Protokollierung ist Ihr Freund, besonders wenn Sie versuchen, Probleme mit der Thread-Synchronisierung zu finden. Foosh vor 9 Jahren 0

1 Antwort auf die Frage

2
Craig Otis

Es scheint, dass Hintergrundjobs, die auf Eingaben warten, in den meisten Umgebungen angehalten werden.

Von der Wikipedia-Seite zu Unix Job Control :

Ein Hintergrundprozess, der versucht, von seinem steuernden Terminal zu lesen oder zu schreiben, wird mit einem SIGTTIN- (für Eingang) oder SIGTTOU-Signal (für den Ausgang) gesendet. Diese Signale stoppen den Prozess standardmäßig, sie können jedoch auch auf andere Weise behandelt werden.

Und von einer Rutgers-Seite zur Zwischennutzung von Unix :

Ein Job, der im Hintergrund ausgeführt wird, wird angehalten, wenn er Eingaben erfordert. Es kann keine Eingabe für einen Hintergrundjob erteilt werden. Stellen Sie daher sicher, dass alle erforderlichen Eingaben für ihn verfügbar sind.

Als Lösung haben wir einfach unseren Java-Prozess aktualisiert, um ein optionales Argument zu akzeptieren, das dazu führt, dass der Haupt-Thread unbegrenzt in den Ruhezustand versetzt wird, anstatt auf die Eingabe zu warten. Wir haben einen Shutdown-Hook, der die SIGTERM/SIGINTSignale entsprechend behandelt:

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