该函数应与Clojure交换!是否应用为幂等的?
我正在经历Clojure Koans,现在我正在玩原子。我的问题与Koans无关,而是一个一般性的问题 考虑Koans的以下(缩短)示例:该函数应与Clojure交换!是否应用为幂等的?,clojure,swap,Clojure,Swap,我正在经历Clojure Koans,现在我正在玩原子。我的问题与Koans无关,而是一个一般性的问题 考虑Koans的以下(缩短)示例: (def atomic-clock (atom 0)) (meditations (= 1 (do (swap! atomic-clock inc) @atomic-clock))) 交换的文档!声明应用于(inc在本例中)的函数可以多次调用,因此该函数应该没有副作用 显然,inc没有副作用,但不是幂等的。
(def atomic-clock (atom 0))
(meditations
(= 1 (do
(swap! atomic-clock inc)
@atomic-clock)))
交换的文档!声明应用于(inc
在本例中)的函数可以多次调用,因此该函数应该没有副作用
显然,
inc
没有副作用,但不是幂等的。这是否意味着,上述断言实际上仍然可能失败?也就是说,在函数确实被多次调用的情况下,原子的值增加了不止一次?否,因为函数将被原始值多次调用。如果交换成功,将不会使用函数生成的新值再次调用函数。“可能再次调用”的情况是,atom的值已被程序的另一部分更改,因此将重试交换。只要您对相同的参数返回相同的结果,这是可以的——但是,如果您从流中读取数据并将其粘贴到atom中,那将是有问题的。传递给swap的函数如果有多个线程争用修改Atom,则可以多次调用code>。但是,只要它没有副作用,只有最后一次调用的返回才会反映在原子的因果历史中。1
以下是一种可能的情况:
线程1尝试(交换!原子钟公司)
线程2尝试同样的操作
线程2设法执行其交换代码>第一个
线程1尝试在atom上进行比较和交换,但失败了,因为其原始值的概念现在已经过时了
线程1重试并成功提交
这里有三个对inc
的调用,两个在线程1上,一个在线程2上
inc
不是幂等元这一事实不是问题
1抽象地考虑;Clojure实际上并不存储atom的历史信息。否,这意味着如果atom上有多个线程交换,函数可能会重试以使用正确的值
想象一下以下执行情况:
线程1:
- 读取原子钟
0
原子钟
- 读取
仍为0原子钟
- inc
原子钟
- 用1更新原子钟应为2
这意味着如果您的函数启动一个火箭,它将启动两个火箭,即使第一次用0调用它并返回1,第二次用1调用它并返回2。谢谢您的解释,明白了。是否有任何涉及实施细节的文档/书籍/博客文章?还是我应该直奔源头?到目前为止,我没有很好地找到任何参考文件。你能给我指出一些吗?Atoms背后的源代码非常简单,所以如果你真的想看到细节,你最好还是深入研究一下。另一方面,如果你想了解原子的语义和Clojure的类似特性,这是一个特别优秀的在线资源。(他还有一篇关于Clojure的STM的文章;在URL中将“Clojure”替换为“STM”以查看它。)还有一些关于Clojure的介绍性书籍;它们都有关于并发特性的章节。