如果我在多个线程之间共享一个 IORef
,并使用 atomicModifyIORef
写入它:
atomicModifyIORef ref (\_ -> (new, ()))
使用普通的旧 readIORef
读取值是否安全?或者在 atomicModifyIORef
修改后,readIORef
是否有可能在另一个线程中返回旧值?
我认为这就是文档的含义:
atomicModifyIORef acts as a barrier to reordering. Multiple atomicModifyIORef operations occur in strict program order. An atomicModifyIORef is never observed to take place ahead of any earlier (in program order) IORef operations, or after any later IORef operations.
我只是想确定一下。
最佳答案
atomicModifyIORef
保证原子读取和后续原子写入之间不会发生任何事情,从而使整个操作原子化。您引用的评论只是指出没有 atomicModifyIORef
s 将并行发生,并且优化器不会尝试重新排序语句来优化程序(在某些情况下可以安全地移动单独的读取和写入;例如在 a' <- read a; b' <- read b; write c $ a' + b'
中,可以安全地重新排序读取)
readIORef
已经是原子的,因为它只执行一个操作。
但是,您正在讨论不同的问题。是的,如果atomicModify
发生在t=3ms
和 read
发生在t=4ms
,您将得到修改后的值。然而;线程不能保证并行运行,所以如果你这样做(伪代码):
forkIO $ do
sleep 100 ms
atomicModify
sleep 1000 ms
read
...不能保证修改后会发生读取(尽管在现代操作系统上这是极不可能的),因为操作系统可能决定以不这样做的方式安排新的短期线程t 并行发生。
关于haskell - 共享 IORef 时,只要我使用atomicModifyIORef 写入,使用 readIORef 读取是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9328023/