为什么动态绑定会影响 future 的 body?
Why does dynamic binding affect the body of future?
我正在尝试重现 Chas 描述的动态变量的缺陷 - http://cemerick.com/2009/11/03/be-mindful-of-clojures-binding/。
考虑以下片段:
(def ^:dynamic *dynamic-x* 10)
(defn adder [arg]
(+ *dynamic-x* arg))
(adder 5) ;; returns 15
(binding [*dynamic-x* 20]
(adder 5)) ;; returns 25
(binding [*dynamic-x* 20]
@(future (adder 5))) ;; returns 25 (!)
实际上,我期望第 3 种情况会 return 15,一旦在单独的线程和当前线程本地值 *dynamic-x*
上执行添加(我应该是 10)应该使用。但是,对我来说出乎意料的是,它 returns 25.
我哪里错了?
future
的设计是将动态绑定传递给将执行未来主体的其他线程(查看 future
的源代码,它遵循 future-call
,它使用一个名为 binding-conveyor-fn
的函数,该函数显式复制线程局部绑定)。
这个 IMO 的动机是,当使用 future
时,你想 运行 在同一个 "logical thread" 中进行计算,只是你实际上是在另一个 [=22] 中进行计算=] 出于性能原因的线程。
我同意它应该被明确记录:)
我正在尝试重现 Chas 描述的动态变量的缺陷 - http://cemerick.com/2009/11/03/be-mindful-of-clojures-binding/。
考虑以下片段:
(def ^:dynamic *dynamic-x* 10)
(defn adder [arg]
(+ *dynamic-x* arg))
(adder 5) ;; returns 15
(binding [*dynamic-x* 20]
(adder 5)) ;; returns 25
(binding [*dynamic-x* 20]
@(future (adder 5))) ;; returns 25 (!)
实际上,我期望第 3 种情况会 return 15,一旦在单独的线程和当前线程本地值 *dynamic-x*
上执行添加(我应该是 10)应该使用。但是,对我来说出乎意料的是,它 returns 25.
我哪里错了?
future
的设计是将动态绑定传递给将执行未来主体的其他线程(查看 future
的源代码,它遵循 future-call
,它使用一个名为 binding-conveyor-fn
的函数,该函数显式复制线程局部绑定)。
这个 IMO 的动机是,当使用 future
时,你想 运行 在同一个 "logical thread" 中进行计算,只是你实际上是在另一个 [=22] 中进行计算=] 出于性能原因的线程。
我同意它应该被明确记录:)