multithreading - Clojure core.async, CPU hangs after timeout. Anyway to properly kill macro thread produced by (go..) block? -
based on core.async walk through example, created below similar code handle cpu intensive jobs using multiple channels timeout of 10 seconds. after main thread returns, cpu usage remains around 700% (8 cpus machine). have manually run nrepl-close in emacs shut down java process.
is there proper way kill macro thread produced (go..) block ? tried close! each chan, doesn't work. want make sure cpu usage 0 java process after main thread returns.
(defn [] returned-str-from-some-cpu-intense-job (do... (str ...))) (let [n 1000 cs (repeatedly n chan)] (doseq [c cs] (go (>! c (returned-str-from-some-cpu-intense-job )))) (dotimes [i n] (let [[result source] (alts!! (conj cs (timeout 10000))) ] ;;wait 10 seconds each job (if (list-contains? cs source) ;;if returned chan belongs cs (prn "ok job finished " result) (prn "job timeout") ))) (doseq [i cs] (close! i)) ;;not useful "killing" macro thread (prn "jobs done")) ;;btw list-contains? function used judge whether element in list ;;http://stackoverflow.com/questions/3249334/test-whether-a-list-contains-a-specific-value-in-clojure (defn list-contains? [coll value] (let [s (seq coll)] (if s (if (= (first s) value) true (recur (rest s) value)) false)))
in repl there seems no clean way yet.
i first tried dirty way using deprecated method thread.stop
(doseq [i @threadpool ] (.stop i))
it seemed worked cpu usage dropped once main thread returned repl, if run program again in repl, it'd hang @ go block part!!
then googled around , found this blog , says
one final thing note: don't explicitly work shutdown go routines. go routines automatically stop operation when main function exits. thus, go routines daemon threads in jvm (well, except "thread" part ...)
so tried again making project uberjar , run on command console, , turned out cpu usage drop when blinking cursor returns console!
Comments
Post a Comment