Haskell STM并重试

时间:2016-03-31 13:20:57

标签: multithreading haskell stm

当我们运行命中webapp1-name的{​​{1}}表达式时,如果条目被修改,则线程被阻塞并且事务再次运行。

但我想知道:

  • 如果我们读取一个STM变量,该变量在导致重试的特定分支中实际上没有使用,那么更新它会尝试再次执行该事务吗?

  • 线程被阻止时,它是否真的被阻止了?或者它是否在线程池中回收以供其他可能等待的操作使用?

2 个答案:

答案 0 :(得分:5)

  1. 是。读取STM变量将调用stmReadTVar - 请参阅here。这将在事务记录中生成新条目,并将在提交时进行检查。如果你看一下here,你会发现ReadTVarOp被标记为具有副作用的操作(has_side_effects = True)所以我认为编译器不会消除它,无论你是否使用它结果。
  2. 正如@WillSewell所写,Haskell使用绿色线程。您甚至可以在单线程运行时使用STM,而无需担心实际的OS线程将被阻止。

答案 1 :(得分:2)

重新。 1:据我了解你的问题,是的,这是正确的;您的整个STM交易将具有与orElse组成的世界包括分支的一致视图(请参阅:https://ghc.haskell.org/trac/ghc/ticket/8680)。但我不确定你的意思是“但我的交易实际上取决于只有1个变量的价值”;如果您执行readTVar,则会跟踪对该变量的更改。

重新。 2:您可以将绿色线程视为已保存计算状态的块状物,这些块状物存储在类似堆栈的物体中并弹出,运行一段时间,并且当它们暂时无法进一步进展时将其重新放回堆栈(“阻止”)或在他们跑了足够长的时间之后。并行发生的程度取决于您告诉运行时使用的 OS线程的数量(通过+RTS -N)。您可以拥有一个使用数千个绿色线程的并发程序,但只能使用一个OS线程运行,这非常好。