Java 在kill时优雅地退出Clojure core.async go循环

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

我有一个顶级的围棋圈。我希望它无限期地运行,至少直到我用CTRL-C或类似的方法发出停止的信号。我目前使用的是:

(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)))