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

Can a channel have multiple consumers?

通读 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. 是否有比重复(复制粘贴或循环)消费者调用代码更惯用的方法?

从任意多个位置从一个频道读取是有效的。每条消息最多会被其中一个阅读。

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

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

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

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

立即关闭通道 returns nil,此版本将在它变为 nil 时停止,而不是进入一个紧密循环,在 nil 上反复消费和调度。