Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure中的线程本地计数器_Clojure_Thread Local - Fatal编程技术网

Clojure中的线程本地计数器

Clojure中的线程本地计数器,clojure,thread-local,Clojure,Thread Local,我有一个web应用程序,我希望能够跟踪给定函数在请求中被调用的次数(即线程) 我知道可以使用ref以非线程本地方式执行,但如何在线程本地执行呢?您可以将的实例保留在ref中。每次需要增加它时,只需增加它的读取值,增加它并返回。在请求开始时,您应该使用0初始化线程本地,因为线程可能会被重新用于不同的请求。您可以使用动态全局变量,绑定到带有绑定的值,并结合特殊的集合以更改其值。与绑定的变量是线程本地变量。每次调用带有计数器的调用中调用的任何形式的my fn时,以下内容将增加*计数器*: (def ^

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


我知道可以使用ref以非线程本地方式执行,但如何在线程本地执行呢?

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

您可以使用动态全局变量,绑定到带有
绑定的值,并结合特殊的
集合
以更改其值。与
绑定的变量是线程本地变量。每次调用带有计数器的
调用中调用的任何形式的my fn时,以下内容将增加
*计数器*

(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

有关更多信息,请参见在
线程本地
中有一个用于此的工具。例如,您可以编写
(def计数器(线程本地(atom 0))
。这将创建一个全局变量,当
deref
ed时,该变量将为每个线程生成一个新的原子。因此,您可以使用
@@counter
读取当前值,或使用
(swap!@counter inc)
增加当前值。当然,您也可以使用
@counter
控制原子本身,并从那时起将其视为普通原子。

在ThreadLocal中保留一个ref肯定比另一种方法更容易吗?我不确定在ref中保留ThreadLocal是否有意义,因为ThreadLocal是可变的,并且不与ref协调;对它们重试的事务仍将中断。这仅在宏的上下文中有效。如果您的代码不是调用方(如ring或HTTP服务器调用您的代码来处理请求),那么它将无法工作。例如:修改
(def
如下:
(def^{:dynamic true}*counter*10)
执行
(使用计数器
,然后检查计数器:
(使用计数器(doall(重复5 my fn))。=>5
*计数器*=>10