7

我有一个网络应用程序,我希望能够跟踪在请求(即线程)中调用给定函数的次数。

我知道可以使用 ref 以非线程本地方式进行操作,但是我将如何在本地进行线程处理?

4

3 回答 3

12

有一个有用的工具叫做thread-local. 例如,您可以编写(def counter (thread-local (atom 0))). 这将创建一个全局变量,当derefed 时,它将为每个线程产生一个新的原子。所以你可以用 读取当前值@@counter,或者用 增加它(swap! @counter inc)。当然,你也可以用它来控制原子本身,@counter然后把它当作一个普通的原子来对待。

于 2011-09-12T17:38:21.197 回答
7

您可以使用动态全局变量,绑定到一个值,binding并结合特殊形式set!来更改其值。绑定的变量binding是线程本地的。*counter*每次调用 my-fn 以在调用中调用任何形式时,以下内容都会增加with-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

于 2011-09-12T11:50:46.007 回答
-1

您可以在 ref中保留ThreadLocal的实例。每次您需要增加它时,只需读取值,增加它并返回。在请求开始时,您应该使用 0 初始化线程本地,因为线程可能会被不同的请求重用。

于 2011-09-12T11:30:24.067 回答