Clojure 中的线程局部计数器
我有一个网络应用程序,我希望能够跟踪请求(即线程)中调用给定函数的次数。
我知道可以使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有用 称为
线程本地
。例如,您可以编写(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, whenderef
ed, 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.您可以使用动态全局变量,通过
binding
绑定到一个值,并结合特殊形式set!
来更改其值。通过binding
绑定的变量是线程本地的。每次为with-counter
调用中调用的任何表单调用 my-fn 时,以下内容都会增加*counter*
:要进行演示,请尝试:
有关详细信息,请参阅 < 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 formset!
to change its value. Vars bound withbinding
are thread-local. The following will increase*counter*
every time my-fn is called for any form called within awith-counter
call:To demonstrate, try:
For more information, see http://clojure.org/vars#set
您可以在参考中保留 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.