当前位置:  开发笔记 > 编程语言 > 正文

在Clojure的Alter vs Commute:我做错了什么?

如何解决《在Clojure的AltervsCommute:我做错了什么?》经验,为你挑选了1个好方法。

Clojure新手在这里,我正在通过优秀的"从头开始的Clojure"帖子,并尝试了这篇文章中的最后一个练习.

当我替换altercommute,总和是不准确的,但我不明白为什么.

(def work (ref (apply list (range 1e5))))
(def sum (ref 0))

(defn trans-alter [work sum]
  (dosync
   (if-let [n (first @work)]
     (do
       (alter work rest)
       (alter sum + n)
       (count @work))
     0)))

(defn trans-commute [work sum]
  (dosync
   (if-let [n (first @work)]
     (do
       (commute work rest)
       (commute sum + n)
       (count @work))
     0)))

(我已经跳过设置期货的代码并调用它们等)

trans-alter这里,我得到4999950000了总和(这是正确的预期值),而trans-commute每次我得到一个不同的值,但高于预期(例如4999998211).

我在这里错过了什么?提前致谢!



1> Arthur Ulfel..:

通勤和改变基本上做同样的事情,虽然通勤对保证正确性稍微宽松一点.

Alter指示STM始终确保此代码一直运行,而不使用它所使用的任何引用.

Commute是一个指令,帮助STM决定何时需要中止事务,因为底层数据从它下面变了.

如果事务中的所有内容都是可交换的,那么即使某些数据发生更改,也可以让该事务完成.在您的情况下,两个交易都可以:

    抓住第一个号码

    从工作中删除相同的号码

    添加相同的数字到结果

    然后commute用来指示STM这是可以的,它应该继续并提交交易...

    得到错误的答案.

因此,简而言之,您要求执行的工作实际上并不是可交换的操作.特别是从列表中删除项目是不可交换的.如果您将任何通勤更改为更改,则第4步将踢出其中一个并且仅允许其中一个完成.被踢出的那个将重新运行新的数据,最终会得到正确的结果.

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有