4

在 Clojure 中,我们使用 STM 进行并发。

我的问题是 STM 使用数据的时间点值,这不是引入歧义吗?

我们怎么知道访问了什么值?

4

2 回答 2

8

Clojure 中的 STM 提供(通过refs 和dosync)一个事务上下文,当从外部世界查看时,所有更新都保证“同时”对所有涉及的 refs 进行。

目标是保持系统中值的一致性,典型的例子是两个银行账户之间的资金转移。例如,如果您将 100 美元从账户 A 转移到账户 B,那么您需要同时更改 A 和 B 的金额。

在这个例子中,对于在事务内部处理的金额,读取的值实际上没有歧义,因为在从事务外部读取完成时,只有以下情况是可能的:

  1. 事务已开始但尚未完成,因此值尚未“正式”更改。事务可以稍后提交或重试,但是当您阅读它们时,这是每个帐户的状态。
  2. 事务已完成,因此读取的金额是修改后的值。

在事务内部时,ref您只读取(并且不修改)的 s可以将它们的值从事务的一个点更改为另一个点,这称为write skew(请参阅Clojure 编程- 第 4 章,Refs,Write Skew)。为了避免这种情况,您可以使用ensure(而不是deref),这将导致如果任何这些refs 的值发生更改(您仅读取的值),则将重试整个事务。

于 2013-06-19T17:09:39.737 回答
4

Clojurians 在这种情况下使用具有非常具体含义的“时间”和“价值”来消除这种歧义。在这种情况下,“时间”是“序列中的时间”或纪元时间,而不是墙上的时间。所以时间描述了这个身份的值序列中的哪个值

价值是身份在某个时间点不变的内容。该值可以是简单的(原始值或原子值)或复合值,由任意结构的不变值组成。重要的部分是值不会改变,所以如果你想知道使用了哪个值,你可以简单地打印或记录它

我强烈推荐这个关于价值观、状态和身份的视频

于 2013-06-19T16:44:04.583 回答