Haskell 哈斯克尔:TVar是如何工作的?

Haskell 哈斯克尔:TVar是如何工作的?,haskell,concurrency,tvar,Haskell,Concurrency,Tvar,TVar是如何工作的?据我所知,它试图在收到所有事务后立即运行它们,但是,事务完成会使当前正在运行的其他事务失效,然后必须重新启动。TVar就是这样工作的吗 如果是这种情况,如果每100毫秒发生1毫秒长的事务,这是否意味着需要200毫秒处理的事务永远不会完成?只要两个事务访问不同的tVAR,它们就可以同时提交,而不会使彼此失效 >为了明确交易无效时,让我们考虑下面的场景: 假设t::TVar Int初始化为0,并在事务a开始时通过readTVar t读取 同时,在另一个线程中,启动事务B,其中

TVar是如何工作的?据我所知,它试图在收到所有事务后立即运行它们,但是,事务完成会使当前正在运行的其他事务失效,然后必须重新启动。TVar就是这样工作的吗


如果是这种情况,如果每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
    被允许提交,我们将得到原子性的违反。)
  • 关于Haskell STM系统的原始论文[1](见第6.5节)回答了您的问题:

    饥饿是可能的。例如,为 很长的时间可能会反复与较短的交易冲突。 我们认为饥饿在实践中不太可能发生,但我们 没有进一步的经验就说不出来。”

    [1] 蒂姆·哈里斯、西蒙·马洛、西蒙·佩顿·琼斯和莫里斯·赫利希。2005年关于并行编程原理和实践的ACM会议(PPoPP'05)

    如果每100毫秒发生1毫秒长的事务,这是否意味着需要200毫秒处理的事务永远不会完成

    只有当它们接触相同的
    TVar
    s时,事务才会发生冲突,因此,如果一些1ms事务避免了受200ms事务影响的所有变量,那么200ms事务将能够完成。此外,由于
    STM
    monad对内部允许的内容非常严格(只有内存访问和纯计算!),因此事务长度之间存在如此大的差异是非常罕见的;通常,它们只有少量的内存读/写长,所有的
    IO
    和其他计算都将在事务之外完成。此外,某个特定事务是否会被其他事务永远阻止是一个调度问题;我不能100%确定GHC当前的调度程序是什么样子的,但它似乎更倾向于旧的(或更高的故障率)事务

    也就是说,livelock是STM的一个非常现实的问题,在更传统的锁并发实现中,它与死锁一样隐蔽,也同样难以解释

    TVar是如何工作的

    您可能会喜欢这篇文章:

    • Tim Harris、Simon Marlow、Simon Peyton Jones和Maurice Herlihy,“可组合内存事务”(预印本PDF)

    。请提供该论文的参考(或DOI)好吗?你的链接不幸被破坏了!blz:我编辑了答案,添加了一个最新的链接。希望它能很快得到批准。