2012-04-20 10 views
5

Risposte ad alcune "potenziali risposte"Uccidere Infinite Loop in Java/Clojure

  • Si dovrebbe cospargere "interrupt" nelle vostre discussioni

    Non scrivo il mio codice con l'intenzione di esso che è un lungo processo/ciclo infinito; è solo che in fase di sviluppo, I accidentalmente codice di scrittura che sembra essere infinito cicli, quindi non posso mai pianificare in anticipo per mettere "controllare se thread got interrupted" nel codice.

Domanda:

Come ho più familiarità con Java/Clojure/Swank e lo sviluppo di codice incrementale. Trovo molto facile per me scrivere accidentalmente una funzione di clojure che finisce per essere un ciclo infinito - ed eseguirlo. Questo poi va avanti, e fissa la JVM, facendo ruotare le ventole del mio portatile - e, in pratica, devo uccidere l'intera JVM per sbarazzarmi di un thread run-away.

Ora, c'è comunque che posso in qualche modo uccidere in sicurezza questi fili del clojure? Sono ben consapevole del fatto che Thread.stop ha varie conseguenze non sicure (come tenere blocchi di cui altri thread potrebbero aver bisogno, ecc ...) - tuttavia, questi qui sono clojure funzioni che sono loop infiniti - e li sto facendo al di fuori di qualsiasi STM - quindi mi chiedo se c'è un modo per uccidere questi thread in modo sicuro.

Grazie!

+0

Dovresti trovare una definizione di cosa sia un ciclo infinito. – Aidanc

+0

(println (intervallo)) è un ciclo infinito. –

+0

Questo è un esempio, non una definizione – Jasper

risposta

7

Non credo che esista una risposta del tutto completa, anche se ci sono alcune cose incomplete ma comunque utili a fare:

  • Per prima cosa ho colpito ctrl-c ctrl-c dal repl che uccide il filo di primo piano che ottiene il 99% dei i miei errori comuni
  • Quindi se fallisce, vado per il terminale e il comando kill.
  • dopo che il suo M-x slime-quit-lisp, clojure-jack-in
+0

Questo non è perfetto, ma questo è buono come credo sarà pratico. –

+0

dal momento che questo è stato pubblicato i comandi di melma cambiati in sidro, ora è sidro-jack-in –

0

In teoria, come detto nei commenti, questo è un problema molto difficile da risolvere veramente.

La migliore speranza per una soluzione pratica ...

Sto assumendo qui che si desidera un modo più affidabile e sicuro di uccidere e di attività di analisi nei fili Clojure che sono in esecuzione. . . E per questo, JPS è la strada da percorrere, dal momento che JPS monitora tutti i processi Java, incluso qualsiasi cosa tu faccia nel clojure standard.

Io uso sempre JPS per questo genere di cose, perché può essere usato per mostrare il processo nomi di classi Java specifiche, compresi i nomi di classe ... La capacità di conoscere la classe che inizialmente invocato un processo che si dà un'idea abbastanza precisa di "cosa" sei tu che stai uccidendo.

doolittle-5:~ Jpeerindex$ jps -l 
61133 jline.ConsoleRunner 
58998 start.jar 
61161 sun.tools.jps.Jps 
51866 jline.ConsoleRunner 

In questo caso, dal momento che "Lein repl" (la repl clojure) viene avviato tramite jline (la classe principale essere ConsoleRunner), possiamo vedere come tale.

Se avete veramente bisogno di vedere i dettagli, è possibile scegliere qualsiasi di questi processi e chiamarli con jstack:

$> jstack 51866

"Gang lavoratore # 0 (Fili GC parallela) "PRIO = 9 tid = 101.802.800 nid = 0x1017f9000 eseguibile

"Gang operaio # 1 (discussioni GC parallelo)" PRIO = 9 tid = 101.803.800 nid = 0x102301000 eseguibile

"Concurrent Mark-Sweep GC Discussione" prio = 9 tid = 10184e000 nid = 0x1093f0000 eseguibile "VM periodico Task Discussione" prio = 10 tid = 1018a4000 nid = 0x10a310000 attesa a condizione

"Eccezione Catcher Discussione" prio = 10 tid = 101.802.000 nid = 0x100704000 eseguibili JNI riferimenti globali: 137

in questo caso, sarete in grado di ottenere un tatto per castrato o non ci sono problemi reali nelle vostre discussioni, identificarli con precisione, e uccidili con fiducia, ecc ...

2

Che dire scrivere una macro in cre mangiato questi cicli e che la macro può iniettare codice nei passaggi del ciclo per controllare periodicamente qualcosa che lo indichi di uscire fuori dal ciclo, come l'esistenza di un file temporaneo su/tmp. Quindi, in pratica, per uscire dal ciclo infinito dovresti solo creare quel file temporaneo.

+0

Penso che questa sia la soluzione migliore in quanto non dipende da nessun particolare ambiente di sviluppo. È possibile sostituire il loop clojure.core/recur standard con quelli personalizzati che controllano un atomo e/o utilizzare un contatore o timer incorporato per limitare il loop e può anche visualizzare informazioni di debug come lo stato corrente del loop quando viene arrestato. – optevo

0

In beta Eclipse/in senso antiorario c'è un'opzione per interrompere manualmente i thread in esecuzione (fuori controllo), senza dover interrompere REPL. Amo questa caratteristica per la stessa ragione per cui vorresti averla.

Fa uso di NREPL 0.2.0 beta, penso attraverso clojure.tools.nrepl.middleware.interruptible-eval. Non solo il client NREPL 0.2.0 di Eclipse/CCW, ma anche l'ultima versione di REPL-y dovrebbe supportare questa funzione (default CTRL-C per fermare il thread, CTRL-D per fermare REPL).