这可以用STM完成吗?

时间:2013-07-06 10:39:42

标签: haskell stm

免责声明:使用MVar ()作为简单的互斥锁即可轻松完成此操作。我只是想知道是否可以用STM完成。

我想原子地执行以下操作:

  • 阅读一些变量。

  • 根据我刚刚阅读的内容决定要执行的I / O.

  • 执行I / O.

  • 将结果记录在变量中。

具体来说,假设我想跟踪我读取的输入字节数,并假设在消耗了一定数量的字节后达到了EOF。 (好吧,让两个线程同时从同一个文件中读取可能是首先要做的事情,但请跟我一起做这个...)

显然,这不能是单个STM交易;中间是I / O.显然,将它作为两个未连接的交易也是错误的。 (两个线程可以看到剩下一个字节的配额,并且都决定读取该字节。)

这个问题有一个很好的解决方案吗?或者STM只是这项任务的错误工具?

3 个答案:

答案 0 :(得分:6)

使用名为TVar Bool的{​​{1}}来跟踪您的IO操作是否正在进行中。在运行IO操作之前,您将一致设置为consistent,并在运行IO操作后将False设置为consistent。然后,任何依赖于您正在修改的STM变量值的操作只会将此子句放在开头:

True

这可确保这些操作只能看到正在修改的变量的一致视图,并且在IO操作正在进行时不会运行。

答案 1 :(得分:4)

我认为您正在寻找stm-io-hooks包。

无论你真正想做什么 - 是否有可能用STM的中止/重试语义来表达?换句话说:你可以做回滚并重复IO动作吗? 如果没有,那么我会参考Gabriel Gonzalez的答案。

答案 2 :(得分:1)

我说STM不能这样做,而且它是故意的。如果事务回滚,则可以在各个位置多次重新启动一段STM代码。如果您运行事务会发生什么,它会执行I / O操作,然后在将结果记录到变量中时回滚?

因此,STM计算必须是纯粹的,只需添加STM基元,如STM可变变量和数组。