10

免责声明:这可以很容易地使用MVar ()一个简单的互斥锁来完成。我只是好奇,看看它是否可以用 STM 完成。

我想以原子方式执行以下操作:

  • 读取一些变量。

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

  • 执行 I/O。

  • 将结果记录在变量中。

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

显然,这不可能是单一的 STM 交易;中间有 I/O。显然,将其视为两个不相关的交易也是错误的。(两个线程可以看到还剩下一个字节的配额,并且都决定读取那个字节。)

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

4

3 回答 3

6

使用TVar Bool命名consistent来跟踪您的 IO 操作是否正在进行中。在运行设置为一致的 IO 操作之前和运行设置为False的 IO 操作之后。然后,任何取决于您正在修改的那些 STM 变量的值的操作只需将此子句放在开头:consistentTrue

do b <- readTVar consistent
   check b
   ...

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

于 2013-07-06T13:41:09.557 回答
4

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

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

于 2013-07-06T14:10:50.450 回答
1

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

出于这个原因,STM 计算必须是纯的,只需要添加 STM 原语,例如 STM 可变变量和数组。

于 2013-07-06T12:18:51.703 回答