[英]Validation in STM transactions nested with orElse
This commentary page describes a lot of the fine details of STM
in GHC, but I'd like clarity on a couple points. 该评论页面描述了GHC中
STM
的许多详细信息,但我想在几点上保持清晰。
First , is a nested transaction invalidated when variables accessed in the parent change? 首先 ,当父级中访问的变量发生更改时,嵌套事务是否无效?
For instance we have in thread A
: 例如我们在线程
A
:
takeTMVar a `orElse` takeTMVar b `orElse` takeTMVar c
Say that while A
is executing the nested transaction takeTMVar b
, another thread B
does a putTMVar a ()
; 假设当
A
执行嵌套事务takeTMVar b
,另一个线程B
执行putTMVar a ()
; can thread A
successfully complete its nested transaction, or is it invalidated (this would strike me as wrong)? 线程
A
可以成功完成其嵌套事务,还是使其无效(这会使我感到错误)?
A second point which I think I understand but wouldn't mind reassurance on: in the case where the entire top-level transaction described above for A
is retried and finally blocks, is it correct that A
will be awoken when any of a
, b
, or c
change? 我想理解的第二点是,但我不介意放心:在上述针对
A
所述的整个顶级交易被重试并最终阻塞的情况下,当a
, b
任何a
被唤醒时, A
是否被唤醒是正确的吗? ,或c
变化?
Finally as a bonus , do the semantics of the transaction above change if we (or library authors) change orElse
to infixr
? 最后,作为奖励 ,做上述变化事务的语义,如果我们(或库的作者)改变
orElse
给infixr
?
I don't think "nested" is the right term to describe this. 我认为“嵌套”是不恰当的描述方式。 These are three alternate transactions;
这是三个备用交易; none is nested within another.
没有一个嵌套在另一个内部。 In particular, exactly one of the three is going to happen and be committed -- but which one happens is not deterministic.
特别是,这三种情况中的一种恰好会发生并被落实-但是发生的哪一种并不确定。 This one sentence should be enough to answer all three questions, but just to be sure, let's carefully say for each:
这句话足以回答所有三个问题,但是请确保为每个问题仔细说一遍:
There's no guarantee. 没有保证。 Maybe
takeTMVar b
will complete and commit; 也许
takeTMVar b
将完成并提交; or maybe it will be pre-empted and takeTMVar a
will be woken up and complete. 否则它将被抢占,而
takeTMVar a
将被唤醒并完成。 But they won't both complete, that's for sure. 但是他们不会全部完成,这是肯定的。
Yes, that's correct: all three TMVar
s can wake this thread up. 是的,这是正确的:所有三个
TMVar
都可以唤醒该线程。
The semantics don't change: whenever several of them can commit, the left-most one will. 语义不会改变:只要其中几个可以提交,最左边的一个就会提交。 (In particular, the paper describing STM says, "The
orElse
function obeys useful laws: it is associative and has unit retry
.".) (特别是描述STM的论文说,“
orElse
函数遵循有用的定律:它是关联的,并且具有单元retry
。”。)
(from your question in the comments) The semantics of STM on page 8 of the linked paper really does guarantee that the left-most successful transaction is the one that succeeds. (摘自您提出的问题)链接的论文第8页STM的语义确实保证了最成功的事务是成功的事务。 So: if thread
A
is executing takeTMVar b
(but has not yet committed) and thread B
executes and commits a write to a
, and nothing else happens afterwards , you can be sure that thread A
will be restarted and return the newly written value from a
. 所以:如果线程
A
正在执行takeTMVar b
(但尚未提交)和线程B
执行,并承诺一个写a
,并没有什么事情发生后 ,你可以肯定的是线程A
将重新启动,并返回来自新写入的值a
。 The "nothing else happens afterwards" part is important: the semantics makes a promise about what happens, but not about how the implementation achieves it; “此后什么也没有发生”部分很重要:语义对发生的事情作出了承诺,但对实现的实现方式不做承诺。 so if, say, another thread took from
a
immediately (so that the takeTMvar a
is still going to retry
), a sufficiently clever implementation is allowed to notice this and not restart thread A
from the beginning of the transaction. 所以,如果说,另一个线程从拿了
a
立即(以便takeTMvar a
仍然在不断retry
),足够聪明的实现是允许注意到这一点,而不是重新启动线程A
从交易的开始。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.