【发布时间】:2013-06-19 16:02:19
【问题描述】:
在 Clojure 中,我们使用 STM 进行并发。
我的问题是 STM 使用数据的时间点值,这不是引入歧义吗?
我们怎么知道访问了什么值?
【问题讨论】:
在 Clojure 中,我们使用 STM 进行并发。
我的问题是 STM 使用数据的时间点值,这不是引入歧义吗?
我们怎么知道访问了什么值?
【问题讨论】:
Clojure 中的 STM 提供(通过 refs 和 dosync)一个事务上下文,当从外部世界查看时,所有更新都保证“同时”对所有涉及的 refs 进行。
目标是保持系统中值的一致性,典型的例子是两个银行账户之间的资金转移。例如,如果您将 100 美元从账户 A 转移到账户 B,那么您需要同时更改 A 和 B 的金额。
在这个例子中,对于交易内部正在处理的金额,读取的值实际上没有歧义,因为在从交易外部读取完成时,只有以下情况是可能的:
当在事务内部时,您只能读取(而不是修改)的refs可以将它们的值从事务的一个点更改为另一个点,这称为 write skew(参见Clojure Programming - 第 4 章,Refs,Write Skew)。为了避免这种情况,您可以使用ensure(而不是deref),这将导致如果这些refs 中的任何一个的值发生变化(您只读取的那些),那么整个事务将被重试.
【讨论】:
Clojurians 在这种情况下使用具有非常具体含义的“时间”和“价值”这两个词来消除这种歧义。在这种情况下,“时间”是“序列中的时间”或纪元时间,而不是墙上的时间。所以时间描述了这个身份的值序列中的哪个值。
价值是身份在某个时间点不变的内容。该值可以是简单的(原始值或原子值)或复合值,由任意结构化的不变值组成。重要的是值不会改变,所以如果您想知道使用了哪个值,您可以简单地打印或记录它
我强烈推荐values, state and identity上的这个视频
【讨论】: