Frage

Responses to some "potential answers"

  • You should sprinkle "interrupts" into your threads

    I don't write my code with the intention of it being a long process / infinite loop; it's just that in development, I accidently write code that happens to be infinite loops, thus I can never plan beforehand to put "check if thread got interrupted" into the code.

Question:

As I get more familiar with Java/Clojure/Swank and incremental code development. I find it very easy for me to accidentally write a clojure function that ends up being an infinite loop -- and run it. This then goes ahead, and pegs the JVM, causing the fans on my laptop to spin up -- and basically, I have to kill the entire JVM to just get rid of one run away thread.

Now, is there anyway I can somehow kill these clojure threads safely? I am well aware that Thread.stop has various unsafe consequences (like holding locks that other threads may need, etc ...) -- however, these here are clojure functions that are infinite looping -- and I'm doing them outside of any STM -- so I'm wondering if there's some way to kill these threads safely.

Thanks!

War es hilfreich?

Lösung

I don't think a fully complete answer exists, though there are some incomplete but still useful things to do:

  • First I hit ctrl-c ctrl-c from the repl which kills the foreground thread which gets 99% of my common mistakes.
  • Then if that fails I go for the terminal and the kill command.
  • after that its M-x slime-quit-lisp, clojure-jack-in

Andere Tipps

What about writing a macro to create these loops and that macro can inject code in the loop steps to periodically check for something that indicates it to exit out of loop, like the existence of a temporary file on /tmp. So basically to exit the infinite loop you would just need to create that temporary file.

In Eclipse/Counterclockwise beta there's an option to manually stop running (out of control) threads, without having to stop the REPL. I love that feature for the same reason you would like to have it.

It makes use of NREPL 0.2.0 beta, I think through clojure.tools.nrepl.middleware.interruptible-eval. Not only the Eclipse/CCW NREPL 0.2.0 client, but also the latest version of REPL-y should support this function (default CTRL-C for stopping thread, CTRL-D for stopping REPL).

Theoretically, as mentioned in the comments, this is a very difficult problem to truly solve.

The best hope for a practical solution...

I'm assuming here that you want a more reliable and safe way of killing and analyzing activity in the clojure threads which are running . . . And for this, JPS is the way to go, since JPS monitors all Java processes, including anything you do in standard clojure.

I always use JPS for this sort of thing, because it can be used to show the process names of specific java classes INCLUDING the class names... The ability to know the class which initially invoked a process gives you a pretty precise idea of "what" youre actually killing.

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

In this case, since "lein repl" (the clojure repl) is started via jline (the main class being ConsoleRunner), we can see it as such.

If you really need to see the details, you can pick any of these processes and call them with jstack :

$>jstack 51866

"Gang worker#0 (Parallel GC Threads)" prio=9 tid=101802800 nid=0x1017f9000 runnable

"Gang worker#1 (Parallel GC Threads)" prio=9 tid=101803800 nid=0x102301000 runnable

"Concurrent Mark-Sweep GC Thread" prio=9 tid=10184e000 nid=0x1093f0000 runnable "VM Periodic Task Thread" prio=10 tid=1018a4000 nid=0x10a310000 waiting on condition

"Exception Catcher Thread" prio=10 tid=101802000 nid=0x100704000 runnable JNI global references: 137

In this case, you'll be able to get a feel for wether or not there are any real issues in your threads, identify them precisely , and kill them with confidence, etc...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top