【发布时间】:2012-04-18 05:40:42
【问题描述】:
据我了解,对IORefs 的修改非常快,所涉及的只是更新一个thunk 指针。当然,读者(即想要在其网页上查看价值的人)将需要花时间评估这些 thunk(如果作者没有回读结果,这可能会增加)。
我认为最好开始并行评估 IORef 上的修改 thunk,因为在许多情况下,它们可能无论如何都必须在某个时候进行评估(显然,这会因无限数据而中断结构)。
所以我写了以下函数,签名与atomicModifyIORef类似:
atomicModifyIORefPar :: (NFData a) => IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORefPar ioref f =
let
g olddata =
let (newdata, result) = f olddata in (newdata, (result, newdata))
in do
(result, newdata) <- atomicModifyIORef ioref g
force newdata `par` return result
这似乎有效 (test code here)。我在这里做错了什么吗?或者有更好的方法吗?
编辑:第二次尝试
灵感来自Carl's answer below。我们实际上将force newdata 存储到IORef 中。无论如何,这与newdata 相同,但它显示了我们想要保留force newdata 以供以后使用的运行时,因此它不会垃圾收集火花。
atomicModifyIORefPar :: (NFData a) => IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORefPar ioref f =
let
g olddata =
let
(newdata, result) = f olddata
newdata_forced = force newdata
in
(newdata_forced, (result, newdata_forced))
in do
(result, newdata_forced) <- atomicModifyIORef ioref g
newdata_forced `par` return result
【问题讨论】:
-
对我来说看起来不错,但不知何故,当原子性很重要时,我会期望
MVar而不是IORef。 -
你不能定义 IORef strict 吗?像 IORef !Bla
-
@VagifVerdi:这不会减慢编写者的速度,还会锁定
IORef,直到计算出修改函数? -
@VagifVerdi 不行,你只能给值构造函数添加严格注解,不能给类型构造函数。 IORef 的值构造函数是隐藏的。 (更不用说克林顿的反对了,即使这可能是有效的。)
-
@VagifVerdi 不。Bla 的内容会很严格,但 IORef 的内容不会很严格。因此,当您对 IORef 进行操作时,您会得到指向 Bla 的未经评估的 thunk。评估其中之一也会导致同时评估其所有严格参数 - 但不是之前。
标签: haskell concurrency ioref