Clojure:阻止使用原子?
Clojure: block the use of an atom?
我有一个并行运行几个线程的 Clojure 代码。它们都共享一个原子:(def counter (atom 0))
由每个线程递增。每 10 分钟,我想使用原子的值执行几个操作,然后将其重置回 0 - 例如:
(defn publish-val []
(let [c @counter]
(email c)
(statsd c)
(print-log c)
(reset! counter 0)))
重要的是 counter
的值从它被取消引用的那一刻到它被重置的那一刻不会改变 - 这意味着当 [=13] 试图改变原子的值时所有线程都应该被阻塞=] 被执行。我该怎么做?
使用代理。
请参阅有关使用它们打印到控制台的 Using agents to serialise access to non-threadsafe resources 部分
除非您已经为您的示例大大简化了问题,否则看起来 swap!
- 将当前计数器值设为零就足够了:
(defn publish-val []
(with-local-vars [c nil]
(swap! counter
(fn [x] (var-set c x) 0))
(email @c)
(statsd @c)
(print-log @c)))
因此,您只需将旧计数器值保存在局部变量中,以原子方式将其与零交换,然后对旧值执行任何需要做的簿记工作——所有这些都不会使任何其他线程的停顿时间超过它需要的时间swap!
我有一个并行运行几个线程的 Clojure 代码。它们都共享一个原子:(def counter (atom 0))
由每个线程递增。每 10 分钟,我想使用原子的值执行几个操作,然后将其重置回 0 - 例如:
(defn publish-val []
(let [c @counter]
(email c)
(statsd c)
(print-log c)
(reset! counter 0)))
重要的是 counter
的值从它被取消引用的那一刻到它被重置的那一刻不会改变 - 这意味着当 [=13] 试图改变原子的值时所有线程都应该被阻塞=] 被执行。我该怎么做?
使用代理。
请参阅有关使用它们打印到控制台的 Using agents to serialise access to non-threadsafe resources 部分
除非您已经为您的示例大大简化了问题,否则看起来 swap!
- 将当前计数器值设为零就足够了:
(defn publish-val []
(with-local-vars [c nil]
(swap! counter
(fn [x] (var-set c x) 0))
(email @c)
(statsd @c)
(print-log @c)))
因此,您只需将旧计数器值保存在局部变量中,以原子方式将其与零交换,然后对旧值执行任何需要做的簿记工作——所有这些都不会使任何其他线程的停顿时间超过它需要的时间swap!