Wie gehen Sie mit der Bereinigung um, wenn das Programm ein Kill-Signal empfängt?
Beispielsweise gibt es eine Anwendung, mit der ich eine Verbindung herstelle und die möchte, dass eine Drittanbieter-App (meine App) finish
beim Abmelden einen Befehl sendet . Was ist das beste Wort, um diesen finish
Befehl zu senden, wenn meine App mit einem zerstört wurde kill -9
?
edit 1: kill -9 kann nicht erfasst werden. Danke Jungs, dass ihr mich korrigiert habt.
edit 2: Ich denke, dieser Fall wäre, wenn derjenige, der gerade kill aufruft, dasselbe ist wie Strg-C
kill -9
bedeutet für mich: "Beginne, fauler Prozess, weg mit dir!", worauf der Prozess aufhören wird zu sein. Sofort.kill
ist nicht dasselbe wie Strg-C, dakill
ohne Angabe des zu sendenden Signals SIGTERM gesendet wird, während Strg-C SIGINT sendet.Antworten:
Es ist für jedes Programm in jeder Sprache unmöglich , mit einem SIGKILL umzugehen. Auf diese Weise ist es immer möglich, ein Programm zu beenden, auch wenn das Programm fehlerhaft oder böswillig ist. SIGKILL ist jedoch nicht das einzige Mittel, um ein Programm zu beenden. Das andere ist, ein SIGTERM zu verwenden. Programme können dieses Signal verarbeiten. Das Programm sollte das Signal durch kontrolliertes, aber schnelles Herunterfahren verarbeiten. Wenn ein Computer heruntergefahren wird, sendet die letzte Phase des Herunterfahrvorgangs jedem verbleibenden Prozess ein SIGTERM, gibt diesen Prozessen einige Sekunden Zeit und sendet ihnen dann ein SIGKILL.
Die Möglichkeit, dies für etwas anderes zu handhaben, als
kill -9
einen Shutdown- Hook zu registrieren . Wenn Sie ( SIGTERM ) verwendenkill -15
können, funktioniert der Shutdown-Hook. ( SIGINT )kill -2
bewirkt, dass das Programm die Shutdown-Hooks ordnungsgemäß beendet und ausführt .Ich habe das folgende Testprogramm unter OSX 10.6.3 ausprobiert und
kill -9
darauf den Shutdown-Hook NICHT wie erwartet ausgeführt. Auf einemkill -15
es DOES das Herunterfahren Haken jedes Mal ausgeführt werden .Es gibt keine Möglichkeit,
kill -9
in einem Programm wirklich elegant mit einem umzugehen.Die einzige echte Option, um mit a
kill -9
umzugehen, besteht darin, ein anderes Watcher-Programm zu überwachen, damit Ihr Hauptprogramm verschwindet oder ein Wrapper-Skript verwendet. Sie können dies mit einem Shell-Skript tun, das denps
Befehl abfragt, der in der Liste nach Ihrem Programm sucht, und entsprechend handelt, wenn es verschwindet.quelle
Es gibt Möglichkeiten, Ihre eigenen Signale in bestimmten JVMs zu verarbeiten - siehe diesen Artikel zum Beispiel über die HotSpot-JVM .
Mit dem internen
sun.misc.Signal.handle(Signal, SignalHandler)
Methodenaufruf von Sun können Sie auch einen Signalhandler registrieren, wahrscheinlich jedoch nicht für Signale wieINT
oderTERM
wie sie von der JVM verwendet werden.Um ein Signal verarbeiten zu können, müssten Sie aus der JVM in das Gebiet des Betriebssystems springen.
Um (zum Beispiel) eine abnormale Beendigung zu erkennen, starte ich meine JVM im Allgemeinen in einem Perl-Skript, lasse das Skript jedoch mithilfe des
waitpid
Systemaufrufs auf die JVM warten .Ich werde dann informiert, wann immer die JVM beendet wird und warum sie beendet wurde, und kann die erforderlichen Maßnahmen ergreifen.
quelle
INT
undTERM
mitsun.misc.Signal
, aber man kann nicht damit umgehen ,QUIT
weil die JVM behält es für das Debuggen, noch ,KILL
weil das Betriebssystem die JVM sofort beendet wird. Wenn Sie versuchen, mit beiden umzugehen, wird einIllegalArgumentException
.Ich würde erwarten, dass die JVM alle von der Anwendung erstellten laufenden Threads ordnungsgemäß unterbricht (
thread.interrupt()
), zumindest für SignaleSIGINT (kill -2)
undSIGTERM (kill -15)
.Auf diese Weise wird das Signal an sie weitergeleitet, was eine ordnungsgemäße Thread-Löschung und Ressourcen-Finalisierung auf die übliche Weise ermöglicht .
Dies ist jedoch nicht der Fall (zumindest in meiner JVM-Implementierung :
Java(TM) SE Runtime Environment (build 1.8.0_25-b17), Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
.Wie andere Benutzer kommentierten, scheint die Verwendung von Shutdown-Hooks obligatorisch zu sein.
Wie würde ich damit umgehen?
Zunächst einmal ist es mir nicht in allen Programmen wichtig, nur in denen, in denen ich Benutzerabbrüche und unerwartete Ziele verfolgen möchte. Stellen Sie sich zum Beispiel vor, Ihr Java-Programm ist ein Prozess, der von anderen verwaltet wird. Möglicherweise möchten Sie unterscheiden, ob es ordnungsgemäß beendet wurde (
SIGTERM
vom Manager-Prozess) oder ob ein Herunterfahren stattgefunden hat (um den Job beim Start automatisch neu zu starten).Als Basis mache ich meine lang laufenden Threads immer regelmäßig auf den unterbrochenen Status aufmerksam und werfe einen,
InterruptedException
wenn sie unterbrochen werden. Dies ermöglicht die Finalisierung der Ausführung auf eine vom Entwickler kontrollierte Weise (und liefert auch das gleiche Ergebnis wie Standardblockierungsvorgänge). Dann wird auf der obersten Ebene des Thread-StapelsInterruptedException
erfasst und eine entsprechende Bereinigung durchgeführt. Diese Threads sind so codiert, dass sie wissen, wie sie auf eine Unterbrechungsanforderung reagieren sollen. Design mit hohem Zusammenhalt .In diesen Fällen füge ich einen Shutdown-Hook hinzu, der genau das tut, was die JVM meiner Meinung nach standardmäßig tun sollte: Unterbrechen Sie alle von meiner Anwendung erstellten Nicht-Daemon-Threads, die noch ausgeführt werden:
Vollständige Testanwendung bei github: https://github.com/idelvall/kill-test
quelle
Sie können verwenden
Runtime.getRuntime().addShutdownHook(...)
, aber Sie können nicht garantieren, dass es auf jeden Fall aufgerufen wird .quelle
Es gibt eine Möglichkeit, auf einen Kill -9 zu reagieren: einen separaten Prozess, der den getöteten Prozess überwacht und bei Bedarf bereinigt. Dies würde wahrscheinlich IPC beinhalten und wäre ziemlich viel Arbeit, und Sie können es trotzdem überschreiben, indem Sie beide Prozesse gleichzeitig beenden. Ich gehe davon aus, dass sich die Mühe in den meisten Fällen nicht lohnt.
Wer einen Prozess mit -9 beendet, sollte theoretisch wissen, was er / sie tut und dass dies zu einem inkonsistenten Zustand führen kann.
quelle