gpt4 book ai didi

clojure - 在并发环境中拍摄复杂可变结构的快照

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

鉴于:各种嵌套集合的复杂结构,引用分散在不同的级别。

需要:一种对这种结构进行快照的方法,同时允许在其他线程中继续写入。

因此,“读者”线程需要在单个长事务中读取整个复杂状态。 “编写器”线程同时在多个短事务中进行修改。据我了解,在这种情况下,STM 引擎会使用 refs 历史记录。

这里我们有一些有趣的结果。例如,读取器在事务开始后 10 秒内到达某个 ref。 Writer 每 1 秒修改一次此 ref。它产生了 10 个 ref 历史值。如果超过了裁判的 :max-history限制,读者事务将永远运行。如果超过 :min-history ,事务可能会重新运行几次。

但实际上读者只需要一个 ref 值(第一个),而作者只需要最近的一个。历史列表中的所有中间值都是无用的。有没有办法避免这种历史过度使用?

谢谢。

最佳答案

对我来说,拥有一个包含大量嵌套引用的大型结构有点“设计味道”。您正在有效地模拟可变对象图,which is a bad idea if you believe Rich Hickey's take on concurrency .

一些不同的想法可以尝试:

  • 在 Clojure 中解决这个问题的惯用方法是将状态放在单个顶级引用中,其中的所有内容都是不可变的。然后读者可以免费获取整个并发状态的快照(甚至不需要事务)。可能很难从您目前所在的位置重构到这一点,但我认为这是最佳实践。
  • 如果您只想让读者获得顶级引用的快照,您可以直接在事务之外取消引用。请注意,内部的 refs 可能会继续发生变异,因此这是否有用取决于您对读者的一致性要求。
  • 您可以在(dosync ...)事务中为读者和作者照常执行所有操作。您可能会遇到争用和事务重试,但这可能不是问题。
  • 您可以创建一个“快照”函数,该函数可以快速遍历图形并取消引用事务中的所有引用,返回删除引用(或替换为新的克隆引用)的结果。读取器调用一次快照,然后在快照完成后继续执行其余的工作。
  • 每次写入完成后,您可以立即拍摄快照,并将其单独存储在原子中。读者可以直接使用它(即只有作者线程直接访问实时数据图)
  • 关于clojure - 在并发环境中拍摄复杂可变结构的快照,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8544990/

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