【发布时间】:2011-11-15 06:30:08
【问题描述】:
我有一个网络应用程序,我希望能够跟踪给定函数在请求(即线程)中被调用的次数。
我知道可以使用 ref 以非线程本地方式进行操作,但我将如何在本地进行线程操作?
【问题讨论】:
标签: clojure thread-local
我有一个网络应用程序,我希望能够跟踪给定函数在请求(即线程)中被调用的次数。
我知道可以使用 ref 以非线程本地方式进行操作,但我将如何在本地进行线程操作?
【问题讨论】:
标签: clojure thread-local
您可以在参考文献中保留ThreadLocal 的实例。每次您需要增加它时,只需读取值,增加它并返回。在请求开始时,你应该用 0 初始化线程本地,因为线程可能会被不同的请求重用。
【讨论】:
您可以使用动态全局变量,绑定到带有binding 的值并结合特殊形式set! 来更改其值。与binding 绑定的变量是线程本地的。每次在 with-counter 调用中调用 my-fn 时,以下内容将增加 *counter*:
(def ^{:dynamic true} *counter*)
(defmacro with-counter [& body]
`(binding [*counter* 0]
~@body
*counter*))
(defn my-fn []
(set! *counter* (inc *counter*)))
为了演示,请尝试:
(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5
欲了解更多信息,请参阅http://clojure.org/vars#set
【讨论】:
(def:(def ^{:dynamic true} *counter* 10) 执行(with-counter,然后检查counter:(with-counter (doall (repeatedly 5 my-fn))) . => 5 *counter* => 10
useful 中有一个名为 thread-local 的工具。例如,您可以写(def counter (thread-local (atom 0)))。这将创建一个全局变量,当derefed 时,将为每个线程生成一个新原子。所以你可以用@@counter读取当前值,或者用(swap! @counter inc)增加它。当然,您也可以使用@counter 获取原子本身,然后将其视为普通原子。
【讨论】: