【问题标题】:Thread/sleep inside Clojure go blockClojure go 块内的线程/睡眠
【发布时间】:2016-11-09 10:42:55
【问题描述】:

我在 Clojure go 块中使用 Thread/sleep 时存在内部冲突。一般不建议在 go 块内有任何长时间运行的进程,Stuart Sierra mentions that sleeping in go block is not preferred:

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

就我而言,我想收听频道上的消息,并将它们分组,然后再通知用户是否快速到达。或者,如果只有一条消息出现,请通知用户。在我的特定用例中,多条消息快速连续或单独出现是很常见的,而且消息不太可能定期出现。

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

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

【问题讨论】:

    标签: multithreading clojure core.async


    【解决方案1】:

    您应该使用clojure.core.async/timeout,而不是阻止Thread/sleep。有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))) 
    

    【讨论】:

    • 非常感谢,超时非常适合我的目的!
    猜你喜欢
    • 2016-03-01
    • 2018-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多