多线程 – 应该把一个`while true`放在一个clojure core.async线程中吗?

我有这样的生产者/消费者模式,我一直在使用core.async线程函数,如下所示:

(defn -db-producer-factory [order-ids-chan next-chan]
  (thread
    (while true
      (do
        (let [order-id (<!! order-ids-chan)]
          (condp = order-id
            :finished (do
                        (>!! next-chan :finished))
            (supress-w-nextexc
              (->>
                ; get denorm'd order
                (-> (r/-get-order :live order-id)
                    denorm/order->denormalized)
                ; put in a map to avoid nils
                (hash-map :data)
                (>!! next-chan)))))))))

但是,当我读取the documentation的线程时,它说:

Executes the body in another thread, returning immediately to the
calling thread. Returns a channel which will receive the result of the
body when completed.

听起来它的期待线程被称为一次性;不是它内置了一个while循环.

我不应该在线程块中执行true吗?或者当我关闭线程的结果时,线程会被清理掉吗?

最佳答案 线程不会被清除,所以,是的,可能你不应该使用true循环.而不是它你可以使用循环退出条件.

常见的模式是使你的常规(简单地说,在其他线程上执行的循环)取决于你的输入通道.换句话说,当关闭为例程提供数据的通道时 – 关闭例程.

我已经重写了你的代码,可能错过了一些东西,但我希望你能得到这个想法:

(defn -db-producer-factory [order-ids-chan next-chan]
  (go-loop [order-id (<! order-ids-chan)]
    (condp = order-id

      nil
      ;; exiting
      nil

      :finished (do
                  (>! next-chan :finished)
                  (recur (<! order-ids-chan)))
      (do
        (supress-w-nextexc
         (->>
          (-> (r/-get-order :live order-id)
              denorm/order->denormalized)
          (hash-map :data)
          (>! next-chan)))
        (recur (<! order-ids-chan))))))

我也用go调用替换了线程调用.这是线程的“轻量级”版本,它使用线程停放而不是阻塞本机线程.如果你需要OS线程,你可以用(thread(loop ….

点赞