ben*_*n w 5 binding clojure thread-local pmap dynamic-variables
有几个老有所博客帖子混合动态变量时,在那里建议谨慎binding
,并且pmap
,如在这里,我们得到了下面的代码片段:
user=> (def *foo* 5)
#'user/*foo*
user=> (defn adder
[param]
(+ *foo* param))
#'user/adder
user=> (binding [*foo* 10]
(doseq [v (pmap adder (repeat 3 5))]
(println v)))
10
10
10
nil
Run Code Online (Sandbox Code Playgroud)
但是,当我运行该代码(将第一行更改为(def ^:dynamic *foo* 5)
)时,不会发生这种情况.我得到三个15
s作为输出(使用Clojure 1.4),就像你天真期望的那样 - 也就是说,传递给pmap的函数看到的绑定形式的变化.线程局部绑定和pmap交互的方式有变化吗?我无法在任何地方找到这个记录.
从1.3开始,本地绑定集与函数一起发送到pmap.所以只要你标记var ^:dynamic就不再是问题了.此功能称为Binding Conveyance,包含在1.3更改日志中:
来自:https://github.com/clojure/clojure/blob/1.3.x/changes.txt
Clojure APIs that pass work off to other threads (e.g. send, send-off, pmap, future) now convey the dynamic bindings of the calling thread: (def ^:dynamic *num* 1) (binding [*num* 2] (future (println *num*))) ;; prints "2", not "1"