Haskell 哈斯克尔:TVar是如何工作的?
TVar是如何工作的?据我所知,它试图在收到所有事务后立即运行它们,但是,事务完成会使当前正在运行的其他事务失效,然后必须重新启动。TVar就是这样工作的吗Haskell 哈斯克尔:TVar是如何工作的?,haskell,concurrency,tvar,Haskell,Concurrency,Tvar,TVar是如何工作的?据我所知,它试图在收到所有事务后立即运行它们,但是,事务完成会使当前正在运行的其他事务失效,然后必须重新启动。TVar就是这样工作的吗 如果是这种情况,如果每100毫秒发生1毫秒长的事务,这是否意味着需要200毫秒处理的事务永远不会完成?只要两个事务访问不同的tVAR,它们就可以同时提交,而不会使彼此失效 >为了明确交易无效时,让我们考虑下面的场景: 假设t::TVar Int初始化为0,并在事务a开始时通过readTVar t读取 同时,在另一个线程中,启动事务B,其中
如果是这种情况,如果每100毫秒发生1毫秒长的事务,这是否意味着需要200毫秒处理的事务永远不会完成?只要两个事务访问不同的
tVAR
,它们就可以同时提交,而不会使彼此失效
<> >为了明确交易无效时,让我们考虑下面的场景:
t::TVar Int
初始化为0
,并在事务a
开始时通过readTVar t
读取李>
B
,其中执行writevar t1
。假设B
在A
之前提交。STM系统将检查是否存在任何不一致,并得出结论认为此时提交B
是安全的,因此现在writevar t1
生效A
无效,因为t
的旧值0
是在A
的开头读取的。(如果A
被允许提交,我们将得到原子性的违反。)TVar
s时,事务才会发生冲突,因此,如果一些1ms事务避免了受200ms事务影响的所有变量,那么200ms事务将能够完成。此外,由于STM
monad对内部允许的内容非常严格(只有内存访问和纯计算!),因此事务长度之间存在如此大的差异是非常罕见的;通常,它们只有少量的内存读/写长,所有的IO
和其他计算都将在事务之外完成。此外,某个特定事务是否会被其他事务永远阻止是一个调度问题;我不能100%确定GHC当前的调度程序是什么样子的,但它似乎更倾向于旧的(或更高的故障率)事务
也就是说,livelock是STM的一个非常现实的问题,在更传统的锁并发实现中,它与死锁一样隐蔽,也同样难以解释
TVar是如何工作的
您可能会喜欢这篇文章:
- Tim Harris、Simon Marlow、Simon Peyton Jones和Maurice Herlihy,“可组合内存事务”(预印本PDF)