我想通过 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
函数变成一个宏,将主体传递到线程池中执行,而不是结果?
当您使用函数时 - 即使用
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")))