Clojure 中的线程局部计数器

发布于 2024-12-04 04:02:59 字数 93 浏览 0 评论 0原文

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

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

I have a web app where i want to be able to track the number of times a given function is called in a request (i.e. thread).

I know that it is possible to do in a non-thread local way with a ref, but how would I go about doing it thread locally?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南笙 2024-12-11 04:02:59

有用 称为线程本地。例如,您可以编写 (def counter (thread-local (atom 0)))。这将创建一个全局变量,当解引用时,将为每个线程生成一个新的原子。因此,您可以使用 @@counter 读取当前值,或使用 (swap!@counter inc) 递增它。当然,您也可以使用 @counter 获取原子本身,然后将其视为普通原子。

There's a tool for this in useful called thread-local. You can write, for example, (def counter (thread-local (atom 0))). This will create a global variable which, when derefed, will yield a fresh atom per thread. So you could read the current value with @@counter, or increment it with (swap! @counter inc). Of course, you could also get hold of the atom itself with @counter and just treat it like a normal atom from then on.

云雾 2024-12-11 04:02:59

您可以使用动态全局变量,通过 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

有关详细信息,请参阅 < a href="http://clojure.org/vars#set" rel="nofollow">http://clojure.org/vars#set

You can use a dynamic global var, bound to a value with binding in combination with the special form set! to change its value. Vars bound with binding are thread-local. The following will increase *counter* every time my-fn is called for any form called within a with-counter call:

(def ^{:dynamic true} *counter*)

(defmacro with-counter [& body]
  `(binding [*counter* 0]
     ~@body
     *counter*))

(defn my-fn []
  (set! *counter* (inc *counter*)))

To demonstrate, try:

(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5

For more information, see http://clojure.org/vars#set

雨落□心尘 2024-12-11 04:02:59

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

You can keep instance of ThreadLocal in ref. And every time you need to increase it just read value, increase it and set back. At the beginning of request you should initialize thread local with 0, because threads may be reused for different requests.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文