2014-01-11 50 views
1

我写了一个独立的uberjar与旋转对开去块像这样一个主要方法:阻止程序终止,而无限期执行块吗?

(defn -main [& args] 
    (let [c (chan)] 
    (go (while true 
      (>! c (rand)))) 
    (go (while true 
      (<! c))))) 

但是,当我执行程序很快终止。为什么?我的意图是让go块无限期地执行。我结束了坚持

(<!! (chan)) 

在主要功能的结束,以防止终止。有没有更好的方法来做到这一点?

+0

所以没有办法干净地退出你的应用程序? – Shepmaster

+0

我依靠Ctrl + C。 – AustinC

+0

@AustinC:这正是你的问题。在设计具有无限调度循环的异步数据流时,您需要自己的取消条件。在'core.async'中,取消通常是通过在生产者端调用'close!'从生产者传递给消费者,然后在消费者端调用'nil'。以下是一些示例代码:https://www.refheap.com/21103 –

回答

1

程序终止,因为在创建那些go块后,主功能完成。无事可做,退出;这应该不是什么惊喜。当然,我们希望主应用程序继续运行,而所有这些go块仍然存在。

这些go块中的每一块都产生一个通道;你可以等到他们中的一个返回一些东西(虽然从现在开始,他们永远不会)。试着用alts!!阻塞而纺线

​​

所以,你的主线程将阻塞,直到在alts!!通道的一个返回值。现在,它会永远阻止,但是这种结构让你更有趣。

(defn -main 
    [& args] 
    (let [c (chan)] 
    (alts!! 
     [(go (while true 
      (>! c (rand)))) 
     (go-loop [value (<! c)] 
       (if (> value 0.8) 
        value ; return value from the go block 
        (recur (<! c))))]))) 

或者去野外,超时后第二:

(defn -main 
    [& args] 
    (let [c (chan)] 
    (alts!! 
     [(go (while true 
      (>! c (rand)))) 
     (go (while true 
      (<! c))) 
     (timeout 1000)]))) 

较大的外卖是,有一个很好的机会。例如,你可以当随机值超过某个阈值退出应用程序你会想要阻止你的主线程等待那些异步的go块来完成他们的业务。