使用claypoole线程池而不预先评估一切

问题描述 投票:0回答:1

我想通过 clojure 中的claypoole 库将要评估的表单作为未来传递给目标线程池。

我尝试将函数体传递给线程池,并且我期望该函数体在线程上而不是内联上进行计算。

我的代码如下所示:

(defn in-thread [thread & body] (claypoole/future thread body))

这被称为:

(defonce pool (claypoole/threadpool 20))

(defn do-something [pool]
  (in-thread pool
    (Thread/sleep 5000)
    (println "foo")))

经过一些测试,我得出的结论是,当我调用

body
时,正在评估
in-thread
,这使得我的整个解决方案实际上没有做任何有意义的事情。我知道我缺少某种基本概念,但每次我尝试研究宏时,我的头都开始旋转。

我如何将

in-thread
函数变成一个宏,将主体传递到线程池中执行,而不是结果?

clojure future
1个回答
0
投票

当您使用函数时 - 即使用

defn
/
fn
创建的构造 - 在调用函数本身之前将评估其所有参数。因此,在您的情况下,会使用
in-thread
(Thread/sleep ...)
results
调用
(println ...)
函数,并且两者都是
nil

为了传递表单而不实际评估它们,您要么必须引用这些表单并稍后使用

eval
,要么使用宏,这是一种更常见的方法。

在您的情况下,将

in-thread
的定义替换为:

就足够了
(defmacro in-thread [thread & body]
  `(claypoole/future ~thread ~@body))

但是,请注意,它只是

claypoole/future
的包装,本身不执行任何操作。并且
claypoole/future
本身 已经是一个宏 - 你甚至不需要
in-thread
!你所需要的一切都已经由
claypoole/future
实现了,所以你可以使用这个:

(defonce pool (claypoole/threadpool 20))

(defn do-something [pool]
  (claypoole/future pool
    (Thread/sleep 5000)
    (println "foo")))
© www.soinside.com 2019 - 2024. All rights reserved.