2014-11-27 47 views
5

Es gibt eine Antwort auf Frage Best Way to Gracefully Shutdown a Java Command Line Program. Ein Herunterfahren-Hook erledigt den Job, wenn ein Programm mit Strg + C beendet wurde.Wie wird eine Java-Anwendung ordnungsgemäß beendet, die beendet wird, nachdem die Befehlszeile geschlossen wurde, von der sie ausgeführt wurde?

Meine Frage ist, wie man elegant beendet, wenn die Befehlszeile selbst während der Ausführung eines Java-Programms geschlossen ist? Ich habe mit Shutdown-Haken getestet, aber es hat in diesem Fall nicht funktioniert. Ich kann in diesem Szenario nicht herausfinden, was mit der virtuellen Maschine passiert. Wird der Prozess und alle seine Threads sofort beendet? Welche Art von Signal erzeugt die Befehlszeile?

Also, wie dieses spezielle Problem gelöst werden kann?

EDIT: Das Problem betrifft Windows-Umgebung.

+0

Antwort http://stackoverflow.com/a/20568883/4428150 erzählt, wie man das von C. – Gustave

Antwort

2

Logisch sollte SIGHUP (terminal Hangup) ausgelöst werden.

Eigentlich habe ich nur meine Vermutung mit einem einfachen Shell-Skript überprüft. Ja, wenn ein Benutzer einen Terminalemulator beendet, in dem eine Anwendung gestartet wurde (und von der sie nicht getrennt wurde), erhält die Anwendung SIGHUP. Richten Sie also einen SIGHUP-Handler ein und reagieren Sie entsprechend. Ein übliches Verhalten ist das Beenden einer Anwendung, aber Ihre Absichten können sich unterscheiden.

Auch wenn Ihre Java-Anwendung STDIN/STDOUT-Operationen ausführt, sollte sie geschlossen oder zumindest neu konfiguriert werden, wenn HUP empfangen wird, da ein Versuch, von einem nicht vorhandenen Terminal zu lesen/schreiben, zu SIGPIPE und/oder Programm führt Block.

Für Windows einen Blick auf Catch Windows terminal closing on running process

+0

Ich bearbeitete meine Frage. Anfangs habe ich Linux- und Windows-basierte Kill-Befehle gemischt. Eigentlich interessiere ich mich besonders für die Windows-Version dieses Szenarios. –

+0

"Windows-Befehlszeile" - cmd.exe? – user3159253

+0

Ja, ich bezog mich auf cmd.exe –

0

Edit für Windows-Umgebung:

ich viel Erfahrung nicht auf Windows-Umgebung, aber wenn Sie Ihre Anwendung laufen halten wollen, ist es als Windows-Dienst im Allgemeinen eingesetzt ist (Es ist ähnlich wie Daemon unter Linux). Normalerweise starten/stoppen/starten Sie den Dienst über ein Dienstprogramm, das alle Dienste auflistet (ich denke, Sie erreichen es über Systemsteuerung -> Verwaltung -> Dienste. Ich würde vermuten, dass das Ausstellen eines "Stopps" über dieses Tool eine anmutige signalisieren würde Herunterfahren. und wenn Sie den Dienst über den Task-Manager zu töten, dann wird es kein ordnungsgemäßes Herunterfahren sein.


Ist das ein Linux oder Windows-basierte Umgebung? in Linux, wenn Sie das Programm im Hintergrund laufen (und beenden Sie die Shell mit dem Befehl "exit"), es wird weiter ausgeführt. Sie können Ihre Anwendung in den Hintergrund stellen, indem Sie am Ende eine & hinzufügen. Auch viele Anwendungen/Dienste laufen im Hintergrund. Wenn Sie ausführen ein Tomcat-Startskript mit dem Befehl startup.sh, wird es auch im Hintergrund weiterlaufen n Sie haben das Terminal beendet, von dem Sie es gestartet haben. Auch am Windows sollte das Konzept ähnlich sein.

In Bezug auf das Schließen der Anwendung verwenden Sie den Befehl kill auf Linux-Systemen. Der Kill-Befehl eines Prozesses sendet ein SIGTERM-Signal an ihn. Anwendungen können Code implementieren, um SIGTERM abzufangen und beim Erkennen eines SIGTERM ordnungsgemäß herunterzufahren. Wenn die Anwendung SIGTERM nicht korrekt behandelt, reagiert sie nicht auf SIGTERM/kill. In diesem Fall müssen Sie ihm explizit ein SIGKILL (kill -9) geben, um es mit Gewalt zu töten. In diesem Fall ist ein ordnungsgemäßes Herunterfahren nicht möglich.

+0

"Wenn Sie das Programm im Hintergrund ausgeführt haben, wird es weiter ausgeführt, auch wenn Sie das Terminal schließen" ist es nicht unbedingt so. – user3159253

+0

hast du recht. Ich werde meinen Kommentar aktualisieren. – Jigish

+0

Lässt man Nohup nicht vergessen, ohne das, was Sie vorschlagen, wäre nicht wahr. – Khanna111

0

In Java gibt es eine spezielle Runtime Methode dafür: addShutdownHook.

Damit können Sie einen Thread initialisieren, den die JVM vor dem Anhalten ausführen möchte.Es ist der Ort, um alle Aufräumarbeiten, die Sie ausführen möchten, auch im Falle von Ctrl-C des Schließens des übergeordneten Fensters zu platzieren. Auszug aus javadoc: Ein Shutdown-Hook ist einfach ein initialisierter aber nicht gestarteter Thread. Wenn die virtuelle Maschine mit dem Herunterfahren beginnt, werden alle registrierten Shutdown-Hooks in einer nicht angegebenen Reihenfolge gestartet und gleichzeitig ausgeführt. Wenn alle Hooks beendet sind, werden alle nicht abgeschlossenen Finisher ausgeführt, wenn die Finalisierung beim Beenden aktiviert wurde. Schließlich wird die virtuelle Maschine angehalten.

Der Abschalt-Hook ist Aufruf, auch wenn das Programm normal endet. In diesem Fall ist es sauberer die registrierte Haken zu entfernen, bevor mit removeShutdownHook (noch eine Methode aus Runtime)

EDIT verlass:

Im Fall von Windows-Umgebung gibt es keine wirklichen Signale, aber spezieller Rückruf, wenn System wird heruntergefahren. AFAIK, der System-Hook wird in diesem Fall korrekt aufgerufen, aber ich gebe zu, dass ich das nie wirklich getestet habe. In Windows können Prozesse mit 2 Möglichkeiten aufgefordert werden, zu beenden:

  • PostQuitMessage Funktion Beiträgen einer WM_QUIT Nachricht in Prozessereignisschleife - normalerweise sollte der Prozess beenden, aber es kann seine Bereinigung (equivallent von Unix SIG_TERM) tut
  • TerminateProcess sofort stoppt den Prozess und alle seine Fäden (equivallent von Unix SIG_KILL)

Console Prozesse können einen ConsoleControlHandler verwenden, die Ctrl-C abfangen kann, Ctrl-Break oder Strg-Close Ereignisse. Die ersten beiden werden über die Tastatur generiert, die letzte wird generiert, wenn der Benutzer die Konsole schließt. Normalerweise sollte die Oracle JVM jedoch den Hook-Mechanismus des Systems verwenden, wenn sie das Ereignis Ctrl-Close erhält, das wie ein SIGTERM verarbeitet wird.

+0

Ich erwähnte Shutdown Hook in meiner Frage. Es funktionierte im Falle von Ctrl-C, aber funktionierte nicht im Falle des Schließens von cmd.exe –

Verwandte Themen