10

我有一个顶级core.async循环。我希望它无限期地运行,至少在我用 CTRL-C 或kill或类似命令停止它之前。我目前正在使用java.lang.Runtime/addShutdownHook,如下所示:

(ns async-demo.core
  (:require [clojure.core.async :as async
             :refer [<! >! <!! timeout chan alt! go]]))
(defn run [] (go (loop [] (recur))))
(.addShutdownHook (Runtime/getRuntime) (Thread. #(println "SHUTDOWN")))

这是我的问题:

  1. 如果我启动 REPL,(run)然后它在后台线程中启动并运行。当我退出 REPL 时,我没有看到所需的关闭消息。

  2. 但是,当我从 运行时lein run,go 循环立即退出并显示“SHUTDOWN”。

也不是我想要的。

我不一定期望找到适用于所有 JVM 的解决方案。我在 Mac 上开发并部署到 Ubuntu,所以我想找到一个适用于两者的解决方案:

  • Mac JVM:Java 版本“1.7.0_45”Java(TM) SE 运行时环境(构建 1.7.0_45-b18)Java HotSpot(TM) 64 位服务器 VM(构建 24.45-b08,混合模式)

  • Ubuntu JVM:java 版本“1.7.0_25”OpenJDK Runtime Environment (IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.12.04.2) OpenJDK 64-Bit Server VM(build 23.7-b01,混合模式)

4

3 回答 3

13

您可以使用信号exit-ch并执行条件来查看是否应该退出循环。alt可以更好地在 clojure 中处理通道 + 条件!:

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

如果你只是close!通道,它不会停止循环运行。此外,不需要启动 go 块来发送值到 channel

于 2018-11-30T14:30:14.760 回答
-1

关于第 1 部分:“当我退出 REPL 时,我没有看到所需的关闭消息。” 我认为关闭线程未连接到lein repl控制台。

关于第 2 部分:go 循环启动后,它在后台线程中运行。由于创建 go 块后主线程退出,因此程序关闭。为了使循环长期存在,它需要放在一个正常的loop. (放入里面也更好Thread/sleep!)

于 2013-12-10T04:19:21.510 回答
-2

go函数返回一个通道。您可能想要(close! chan)关闭挂钩。

如果你运行lein run,你需要一个 main 函数来调用(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)))
于 2013-12-10T11:27:02.553 回答