Multithreading Clojure:阻止原子的使用?
我有一个Clojure代码,它并行运行几个线程。它们都共享一个原子:Multithreading Clojure:阻止原子的使用?,multithreading,clojure,atomic,Multithreading,Clojure,Atomic,我有一个Clojure代码,它并行运行几个线程。它们都共享一个原子:(def counter(atom 0)),该原子由每个线程递增。每10分钟,我想使用atom的值执行几个操作,然后将其重置为0-例如: (defn publish-val [] (let [c @counter] (email c) (statsd c) (print-log c) (reset! counter 0))) 重要的是,计数器的值从解除引用到重置时不会改变-这意味着在执行pu
(def counter(atom 0))
,该原子由每个线程递增。每10分钟,我想使用atom的值执行几个操作,然后将其重置为0-例如:
(defn publish-val []
(let [c @counter]
(email c)
(statsd c)
(print-log c)
(reset! counter 0)))
重要的是,计数器
的值从解除引用到重置时不会改变-这意味着在执行publish val
时,当试图改变atom的值时,应阻止所有线程。我如何做到这一点?使用代理
请参阅有关使用代理打印到控制台的部分
请参阅关于使用它们打印到控制台的部分除非您已经大大简化了示例中的问题,否则在这里用零表示当前计数器值就足够了:
(defn publish-val []
(with-local-vars [c nil]
(swap! counter
(fn [x] (var-set c x) 0))
(email @c)
(statsd @c)
(print-log @c)))
因此,您只需将旧计数器值保存在一个局部变量中,以原子方式将其与零交换,然后对旧值执行任何簿记操作,所有这些操作都不会使任何其他线程暂停超过
交换所需的时间代码>除非您已经大大简化了示例中的问题,否则在这里用零表示当前计数器值就足够了:
(defn publish-val []
(with-local-vars [c nil]
(swap! counter
(fn [x] (var-set c x) 0))
(email @c)
(statsd @c)
(print-log @c)))
因此,您只需将旧计数器值保存在一个局部变量中,以原子方式将其与零交换,然后对旧值执行任何簿记操作,所有这些操作都不会使任何其他线程暂停超过交换所需的时间代码>我认为(使用本地变量[c nil](重置!计数器(do(var set c@counter)0))(println@c))
在这里更准确。。有什么原因让你更喜欢swap代码>和fn[c]
?@shakedzy-使用交换代码>保证原子性。如果您使用重置相反,在读取@counter
和调用(reset!counter 0)
之间,您可能会丢失一些对计数器的更新。我认为(使用本地变量[c nil](reset!counter(do(var set c@counter)0))(println@c))
在这里更准确。。有什么原因让你更喜欢swap代码>和fn[c]
?@shakedzy-使用交换代码>保证原子性。如果您使用重置
相反,在读取@counter
和调用(重置!计数器0)
之间,您可能会丢失对计数器的一些更新。