Ich habe einen Clojure-Code, der ein paar Threads parallel läuft. Sie teilen sich alle ein Atom: (def counter (atom 0))
, das von jedem Thread inkrementiert wird. Jede 10 Minuten, würde Ich mag verschiedene Aktionen mit dem Wert des Atoms führen und es dann auf 0 zurückgesetzt - zum Beispiel:Clojure: Blockieren Sie die Verwendung eines Atoms?
(defn publish-val []
(let [c @counter]
(email c)
(statsd c)
(print-log c)
(reset! counter 0)))
Es ist wichtig, dass der Wert von counter
nicht von dem Moment ändern Es ist dereferenziert auf den Moment, wenn es zurückgesetzt wird - was bedeutet, dass alle Threads blockiert werden sollten, wenn versucht wird, den Wert des Atoms zu ändern, während publish-val
ausgeführt wird. Wie mache ich das?
Ich denke '(mit-lokalen-vars [c nil] (Reset! counter (do (var-set c @ counter) 0)) (println @c)) 'ist genauer hier .. gibt es einen Grund, warum Sie' swap! 'und' fn [c] 'bevorzugten? – shakedzy
@shakedzy - Die Verwendung von 'swap!' Garantiert die Atomarität. Wenn Sie stattdessen 'reset!' Verwenden, verlieren Sie möglicherweise einige Aktualisierungen zu 'counter' zwischen dem Lesen von' @ counter' und dem Aufruf von '(reset! Counter 0)'. – DaoWen