Java 在kill时优雅地退出Clojure core.async go循环
我有一个顶级的围棋圈。我希望它无限期地运行,至少直到我用CTRL-C或类似的方法发出停止的信号。我目前使用的是:Java 在kill时优雅地退出Clojure core.async go循环,java,clojure,signals,core.async,Java,Clojure,Signals,Core.async,我有一个顶级的围棋圈。我希望它无限期地运行,至少直到我用CTRL-C或类似的方法发出停止的信号。我目前使用的是: (ns async-demo.core) (:require[clojure.core.async:as async) :参考! 以下是我的问题: 如果我启动REPL并(运行),那么它将在后台线程中启动并运行。当我退出REPL时,我看不到所需的关闭消息 但是,当我从lein run运行时,go循环立即退出并显示“SHUTDOWN” 这也不是我想要的 我不一定希望找到一个适用于所有JV
(ns async-demo.core)
(:require[clojure.core.async:as async)
:参考!
以下是我的问题:
如果我启动REPL并(运行)
,那么它将在后台线程中启动并运行。当我退出REPL时,我看不到所需的关闭消息
但是,当我从lein run
运行时,go循环立即退出并显示“SHUTDOWN”
这也不是我想要的
我不一定希望找到一个适用于所有JVM的解决方案。我在Mac上开发并部署到Ubuntu,所以我想找到一个同时适用于以下两种情况的解决方案:
- Mac JVM:java版本“1.7.0_45”java(TM)SE运行时环境(构建1.7.0_45-b18)java热点(TM)64位服务器虚拟机(构建24.45-b08,混合模式)
- Ubuntu JVM:java版本“1.7.0_25”OpenJDK运行时环境(IcedTea 2.3.10)(7u25-2.3.10-1ubuntu0.12.04.2)OpenJDK 64位服务器虚拟机(构建23.7-b01,混合模式)
关于第1部分:“当我退出REPL时,我没有看到所需的关闭消息。”我认为关闭线程没有连接到
lein REPL
的控制台
关于第2部分:go循环启动后,它在后台线程中运行。由于主线程在创建go块后退出,程序将关闭。为了使循环长期存在,需要将其放入一个正常的循环
(将线程/睡眠
放入其中也更好!)go
函数返回一个频道。您可能希望在关机挂钩中(关闭!chan)
如果运行leinrun
,则需要一个调用(run)
的主函数来启动go线程
(ns async-demo.core
(:require [clojure.core.async :as async
:refer [<! >! <!! timeout chan alt! go close!]]))
(def ch (atom nil))
(defn run []
(go (while true
(<! (timeout 500))
(prn "inside go"))))
(defn -main [& args]
(println "Starting")
(reset! ch (run))
(.addShutdownHook (Runtime/getRuntime)
(Thread. #(do
(println "SHUTDOWN")
(close! @ch))))
(while true
(<!! @ch)))
(ns async-demo.core)
(:require[clojure.core.async:as async)
:请参阅[!您可以使用信令退出ch
并执行一个条件,以查看是否应退出循环。在clojure中,通道+条件最好通过以下方式处理:
如果您只关闭通道,它不会停止循环的运行。另外,请参见:请参见:当您(a)从REPL运行时,您是否看到关机消息;(b)通过lein run运行
?案例(a)lein REPL
,案例(b)中没有关机消息lein run
是否显示关机如果我使用Ctrl-D
或使用(退出)
功能退出时运行lein trompoline repl
关机显示,我不明白为什么这是一个可接受的答案。这是错误的,因为从外部关闭go
返回的频道不会在循环时停止
(ns async-demo.core
(:require [clojure.core.async :refer [chan go-loop alt! timeout put!]]))
(defn run
[]
(let [exit-ch (chan)]
(go-loop []
(alt!
(timeout 10) (recur)
exit-ch nil
exit-ch
(let [exit-ch (run)]
(.addShutdownHook (Runtime/getRuntime) (put! exit-ch true)))