2016-11-09 93 views
3

我在Clojure去块中使用线程/睡眠有内部冲突。所以一般不建议有内部的任何长期运行的进程去块,Stuart Sierra mentions that sleeping in go block is not preferredClojure去块中的线程/睡眠

一般情况下,它不会阻塞,睡眠,还是我的任何工作/ O可以被安全地放置在一展身手而不会对系统的吞吐量产生重大影响。

在我的情况下,我想收听某个频道上的信息,并在通知用户它们来之前将它们分组。或者,如果只有一条消息出现,请通知用户。在我的特殊使用案例中,很多消息要么快速连续发布,要么独自发布,而且消息不可能定期发布。

为了实现这一点,我有一个go-loop块,等待通道上的输入。当它收到时,它睡一会儿(最多一两秒钟),同时检查是否有任何其他输入到达频道,并基于此通知用户整个事情或只传递第一条消息。

我不会在我的应用程序中有一堆这样的go块,只有一块。由于Clojure总是会产生更多的线程来服务块,因此在睡眠中阻塞一个线程在实践中应该不成问题。但是从理论上讲,我不知道是否有一种更优雅的方式来处理这个问题,而不需要像这样绑定一个线程?

回答

9

而不是阻止在Thread/sleep你应该使用clojure.core.async/timeout。有an example on ClojureDocs非常类似于你的场景:

(go-loop [seconds (atom 0) 
      add-seconds! #(swap! seconds + %)] 
    (println "Waiting 1 second") 
    (<! (timeout 1000)) 
    (add-seconds! 1) 
    (println "Waiting 2 seconds") 
    (<! (timeout 2000)) 
    (add-seconds! 2) 
    (println 
    (format "Waited %s seconds" 
      @seconds))) 
+0

感谢一堆,超时是完美的我的目的! – Domchi