免责声明:使用MVar ()
作为简单的互斥锁即可轻松完成此操作。我只是想知道是否可以用STM完成。
我想原子地执行以下操作:
阅读一些变量。
根据我刚刚阅读的内容决定要执行的I / O.
执行I / O.
将结果记录在变量中。
具体来说,假设我想跟踪我读取的输入字节数,并假设在消耗了一定数量的字节后达到了EOF。 (好吧,让两个线程同时从同一个文件中读取可能是首先要做的事情,但请跟我一起做这个...)
显然,这不能是单个STM交易;中间是I / O.显然,将它作为两个未连接的交易也是错误的。 (两个线程可以看到剩下一个字节的配额,并且都决定读取该字节。)
这个问题有一个很好的解决方案吗?或者STM只是这项任务的错误工具?
答案 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可变变量和数组。