一个频道可以有多个消费者吗?

时间:2015-01-06 17:41:56

标签: asynchronous clojure

阅读Core Async walkthrough我认为我没有看到这个用例。我有一个生产者和许多相同的消费者。

(def mychan (chan))
(defn my-expensive-fn [arg] (prn-expensively arg))

; four identical consumers
(go (while true (my-expensive-fn (<!! mychan))))
(go (while true (my-expensive-fn (<!! mychan))))
(go (while true (my-expensive-fn (<!! mychan))))
(go (while true (my-expensive-fn (<!! mychan))))

; something generating lots of items
(doseq [item in lots-of-items]
    (something-expensive)
    (>!! mychan item))
  1. 有效吗?
  2. 是否有更惯用的方式来做这件事而不是重复(复制粘贴或循环)消费者调用代码?

1 个答案:

答案 0 :(得分:2)

从您喜欢的任意位置读取频道是有效的。每封邮件最多只能被其中一封阅读。

您可以在循环中创建相同的块,而不是复制粘贴代码。

(dotimes [_ 4]
  (go
    (while true
      (my-expensive-fn (<!! mychan)))))

你将在这里看到的一个问题是循环没有会阻止递归的条件,如果频道关闭,至少停止更有意义。

(dotimes [_ 4]
   (go-loop [job (<!! mychan)]
     (when (some? job)
       (my-expensive-fn job)
       (recur (<!! mychan)))))

一个封闭的通道立即返回nil,这个版本将在它变为零时停止,而不是在nil上反复消耗和调度的紧密循环。