我有这样的生产者/消费者模式,我一直在使用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 ….