Clojure中的线程/睡眠去块

Dom*_*chi 3 multithreading clojure core.async

我在Clojure go块中使用Thread/sleep存在内部冲突.通常不建议在go块内部使用任何长时间运行的进程,Stuart Sierra提到在go块中睡觉不是首选:

通常,任何不阻塞,休眠或执行I/O的工作都可以安全地放入go块中,而不会对系统的吞吐量产生重大影响.

在我的情况下,我想听一个频道上的消息,并在通知用户他们是否快速进入之前对它们进行分组.或者,如果只有一条消息出现,请通知用户.在我的特定用例中,几个消息快速连续或单独发送是很常见的,并且消息不可能定期发送.

为此,我有一个go-loop等待通道输入的块.当它接收到它时会睡眠一点(最多一秒或两秒),检查在此期间是否有任何其他输入到达通道,并基于此通知用户有关整件事或只是传递第一条消息.

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

Pio*_*dyl 9

而不是阻止Thread/sleep你应该宁愿使用clojure.core.async/timeout.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))) 
Run Code Online (Sandbox Code Playgroud)