Clojure core.async,CPU在超时后挂起.无论如何要正确杀死(go ..)块产生的宏线程?

Kev*_*Zhu 7 multithreading asynchronous clojure core.async

基于core.async遍历示例,我在下面创建了类似的代码,以使用多个通道处理一些CPU密集型作业,超时为10秒.但是在主线程返回后,CPU使用率仍然保持在700%左右(8台CPU机器).我必须在emacs中手动运行nrepl-close来关闭Java进程.

是否有任何正确的方法来杀死(go ..)块产生的宏线程?我试过了!每个陈,但它不起作用.我希望在主线程返回后确保Java进程将CPU使用率恢复为0.

(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 for 10 seconds for each job
      (if  (list-contains? cs source)  ;;if returned chan belongs to cs 
        (prn "OK JOB FINISHED " result)
        (prn "JOB TIMEOUT")
        )))

 (doseq [i cs]
   (close! i))  ;;not useful for "killing" macro thread

 (prn "JOBS ARE DONE"))

;;Btw list-contains? function is used to judge whether an element is in a 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)))
Run Code Online (Sandbox Code Playgroud)

Kev*_*Zhu 2

在 REPL 中似乎还没有干净的方法。

我首先尝试了一种非常肮脏的方法,使用已弃用的方法 Thread.stop

 (doseq [i @threadpool ]
              (.stop i))
Run Code Online (Sandbox Code Playgroud)

它似乎有效,因为一旦主线程返回 REPL,CPU 使用率就会下降,但如果我在 REPL 中再次运行该程序,它只会挂在 go 块部分!

然后我用谷歌搜索,找到了这个博客,上面写着

最后要注意的一件事:我们没有明确执行任何工作来关闭 go 例程。当 main 函数退出时,Go 例程将自动停止运行。因此,Go 例程就像 JVM 中的守护线程(好吧,除了“线程”部分......)

于是我再次尝试将我的项目制作成uberjar并在命令控制台上运行它,结果发现当闪烁的光标返回到控制台时CPU使用率会立即下降!