首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在未来和未来在未来

在未来和未来在未来
EN

Stack Overflow用户
提问于 2017-11-07 16:00:53
回答 2查看 115关注 0票数 0

我有下面的代码

代码语言:javascript
复制
(def number (ref 0))

(dosync (future (alter number inc)))  ; A
(future (dosync (alter number inc)))  ; B

第二个成功了,但是第一个no transaction is running失败了。但它是包在卷宗里的,对吧?

clojure还记得基于在哪个线程中创建的事务打开吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-07 16:08:53

你是对的。dosync的全部目的是在当前线程中开始一个事务。future在一个新线程中运行其代码,因此,如果A不在其线程的dosync中,则alter将不存在。

对于案例B,alterdosync都在同一个(新的)线程中,所以没有问题。

票数 2
EN

Stack Overflow用户

发布于 2017-11-07 20:31:36

这不起作用的原因有很多。正如Alan所写的,事务被归为单个线程,因此,当您创建一个新线程时,您将丢失事务。

另一个问题是dosync的动态范围。如果你写了同样的问题

代码语言:javascript
复制
((dosync #(alter number inc)))

在这里,我们在dosync范围内创建一个函数,并让该函数成为dosync的结果。然后我们从dosync块外部调用函数,但是事务当然不再运行。

这与您使用future所做的非常相似:future创建一个函数,然后在一个新线程上执行它,返回一个句柄,您可以用来检查该线程的进度。即使允许跨线程事务,这里也有一个争用条件:dosync块是在执行future中的alter调用之前还是之后关闭其事务?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47162315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档