gpt4 book ai didi

clojure - 获取原子的状态,并以原子方式重置它

转载 作者:行者123 更新时间:2023-12-04 14:23:49 25 4
gpt4 key购买 nike

我正在写一个 Mandelbrot Set实现,并加速找出哪些点变为无穷大,我决定尝试使用 ExecutorService并行检查点。

基本上计划是:

  • 计算我需要找到的所有点
  • 给每分给服务
  • 让服务将其结果转储到 Atom包装 vector生产时
  • 定期有绘图代码抓取生成的结果,并清空队列

  • 我的问题是最后一点。如何安全地从原子中获取先前的结果并重置它?

    我想到了一个简单的方法:
    (def draw-queue-A (atom []))

    (defn grab-and-clear-queue []
    (let [results @draw-queue-A]
    (reset! draw-queue-A [])
    results))

    但这看起来不安全。如果在取消引用和 reset! 之间添加了某些内容,就会丢失。

    我目前确定的可憎恶行是​​:
    (defn grab-and-clear-queue []
    (let [results (atom [])]
    (swap! draw-queue-A
    (fn [res] (reset! results res)
    []))
    results))

    但是使用原子来检索结果似乎很荒谬。

    我怎样才能理智地检索原子的内容,并在不丢失任何结果的情况下重置它?

    最佳答案

    目前有JIRA ticket处理这个请求。同时,这可以满足您的需求,并且类似于补丁中的内容,尽管我只浏览了代码:

    (defn reset-return-old!
    [atm new-value]
    (let [old-value @atm]
    (if (compare-and-set! atm old-value new-value)
    (do
    (.notifyWatches atm old-value new-value)
    old-value)
    (recur atm new-value))))

    我们依赖于 CAS 语义,就像 swap! 做。我们有效地旋转以保证我们在读取和 CAS 之间不会被中断(虽然我认为这仍然是 ABA problem 的牺牲品,但我认为在这种情况下这并不重要)。

    我正在通知上面的 watch ——如果你没有 watch ,为了你的目的,你可以消除它和 do块以进一步简化。

    关于clojure - 获取原子的状态,并以原子方式重置它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43599473/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com