2013-12-10 48 views
8

私はトップレベルのcore.async goループを持っています。少なくともCTRL-Cまたはkillなどで停止するように通知するまで、無期限に実行します。私は現在、このようなjava.lang.Runtime/addShutdownHookを使用しています:ここで終了時にClojureのcore.async goループを正常に終了します

(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ループがすぐに終了し、「シャットダウン」と表示されます。

どちらも希望しません。

私は、必ずしもすべてのJVMで動作する解決策を見つけるとは限りません。私は、Mac上で開発とUbuntuにデプロイするので、私は両方のために働く解決策を見つけるしたいと思います:

  • マックJVM:Javaのバージョン「1.7.0_45」Javaの(TM)SEランタイム環境(ビルドJava HotSpot(TM)64ビットサーバーVM(ビルド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ビットサーバーVM(パート1について23.7-B01、混在モード)

+0

も参照してください:http://stackoverflow.com/questions/11709639/how-to-catch-ctrlc-in-clojure –

+0

参照します:http://stackoverflow.com/questions/18612063/clojure- core-async-cpu-hangs-after-timeout –

答えて

4

go関数はチャンネルを返します。シャットダウンフックには(close! chan)が必要です。

lein runを実行する場合は、(run)と呼ばれる主な機能が必要です。

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

(a)REPLから実行したときにシャットダウンメッセージが表示されます。 (b)「lein run」を介して実行しますか? –

+0

(a) 'lein repl'の場合はシャットダウンメッセージがありません。ケース(b)' lein run'がシャットダウンを表示します – edbond

+0

'Ctrl-D 'で終了すると' lein trampoline repl'シャットダウン表示を実行し、 (exit) 'function – edbond

-1

を構築:「私が終了するとREPL、私は希望のシャットダウンメッセージが表示されません。私はシャットダウンスレッドがlein replのコンソールに接続されていないと思う。

第2部:goループが開始されると、バックグラウンドスレッドで実行されます。 goブロックの作成後にメインスレッドが終了するので、プログラムはシャットダウンします。ループを長くするには、通常のloopに入れる必要があります。 (Thread/sleepを入れるのも良い方法です!)

+1

goブロックがスレッドで実行されない –

関連する問題