Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 应该将'while true'放在clojure core.async线程中吗?_Multithreading_Clojure_Core.async - Fatal编程技术网

Multithreading 应该将'while true'放在clojure core.async线程中吗?

Multithreading 应该将'while true'放在clojure core.async线程中吗?,multithreading,clojure,core.async,Multithreading,Clojure,Core.async,我用core.asyncthread函数制作了一个生产者/消费者模式,如下所示: (defn -db-producer-factory [order-ids-chan next-chan] (thread (while true (do (let [order-id (<!! order-ids-chan)] (condp = order-id :finished (do

我用core.async
thread
函数制作了一个生产者/消费者模式,如下所示:

(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)))))))))
(defn-db生产商工厂[订单ID chan next chan]
(线程
(虽然是真的
(做
(let[订单id(!!下一张:完成))
(Suppress-w-Nextex)
(->>
;获得正式订单
(->(r/-get-order:live-order-id)
非规范化/订单->非规范化)
;放一张地图以避免零
(哈希映射:数据)
(>!!下一个成龙(()()())()))))
但是,当我阅读
线程
时,它会说:

在另一个线程中执行主体,并立即返回到 调用线程。返回一个通道,该通道将接收 完成后返回正文

这听起来像是它期望线程被一次性调用;而不是它是为
而构建的,而
是在它内部循环的


我是否应该在
线程
块中执行
而为true
操作?或者当我关闭
线程
的结果chan时线程是否会被清除?

线程肯定不会被清除,因此,是的,您可能不应该使用
而为true
循环。您可以使用带有退出条件的循环来代替它

常见的模式是使您的
go
-例程(简单地说,在其他线程上执行的循环)依赖于您的输入通道。换句话说,当为
go
-例程提供数据的通道关闭时-
go
-例程关闭

我稍微重写了您的代码,可能遗漏了一些内容,但我希望您能理解:

(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))))))
(defn-db生产商工厂[订单ID chan next chan]
(go loop[订单id(!下一个chan:已完成)
(复发率>
(->(r/-get-order:live-order-id)
非规范化/订单->非规范化)
(哈希映射:数据)
(>!next chan)))
(重现(

我还将
thread
调用替换为
go
调用。这是
thread
的“轻量级”版本,它使用线程驻车而不是阻止本机线程。如果您需要操作系统线程,您可以将其替换为
(线程(循环…
)请参阅此处的讨论:

最重要的一句话是:

当你需要时,你应该使用线程而不是go块的原因 执行长时间运行的任务是为了避免阻塞线程池

长时间运行的任务正是Java线程的用途。既然您有一个长时间运行的任务(看起来是?),它应该有自己的线程


JVM可以在现代硬件上处理上千个用户线程w/o问题。

我很难相信
线程
中的
循环
能够被处理/释放/垃圾收集,但你确实回答了我的问题!在clojure#core async slack room为我解决了这个问题。谢谢!这个问题不是关于hav的这是关于拥有一个长时间运行的线程,即使不再需要它,它仍会继续运行,这可能会导致内存泄漏。