5

这个评论页面描述了 GHC 中的许多细节STM,但我想澄清几点。

首先,当父级中访问的变量发生变化时,嵌套事务是否失效?

例如我们在线程中有A

takeTMVar a `orElse` takeTMVar b `orElse` takeTMVar c

假设在A执行嵌套事务takeTMVar b时,另一个线程B执行putTMVar a ();线程可以A成功完成其嵌套事务,还是无效(这会让我觉得错了)?

我认为我理解但不介意保证的第二点:在重试上述整个顶级事务A并最终阻塞的情况下,当任何,或更改A时将被唤醒是否正确?abc

最后作为奖励,如果我们(或库作者)更改orElse为,上述事务的语义是否会更改infixr

4

1 回答 1

5

我不认为“嵌套”是描述这一点的正确术语。这是三个替代交易;没有一个嵌套在另一个中。特别是,这三者中的一者将发生并承诺——但哪一个发生并不确定。这句话应该足以回答所有三个问题,但为了确定起见,让我们为每个问题仔细说:

  1. 没有保证。也许takeTMVar b会完成并提交;或者它可能会被抢占并被takeTMVar a唤醒并完成。但他们不会都完成,这是肯定的。

  2. 是的,这是正确的:所有三个TMVars 都可以唤醒这个线程。

  3. 语义不会改变:只要其中几个可以提交,最左边的就会提交。(特别是,描述 STM 的论文说,“orElse函数遵循有用的规律:它是关联的并且有单位retry。”。)

  4. (来自您在评论中的问题)链接论文第 8 页上的 STM 语义确实保证了最左边的成功交易成功的交易。所以:如果线程A正在执行takeTMVar b(但尚未提交)并且线程B执行并提交了对 的写入a之后没有其他任何事情发生,您可以确定线程A将重新启动并返回新写入的值a。“之后没有其他事情发生”部分很重要:语义对发生的事情做出承诺,而不是关于实现如何实现它;因此,如果说,另一个线程a立即取自(这样takeTMvar a仍然会retry),一个足够聪明的实现可以注意到这一点,而不是A从事务的开始重新启动线程。

于 2014-01-18T00:10:12.807 回答