haskell - 共享 IORef 时,只要我使用atomicModifyIORef 写入,使用 readIORef 读取是否安全?

标签 haskell thread-safety ioref

如果我在多个线程之间共享一个 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=3msread发生在t=4ms ,您将得到修改后的值。然而;线程不能保证并行运行,所以如果你这样做(伪代码):

forkIO $ do
  sleep 100 ms
  atomicModify
sleep 1000 ms
read

...不能保证修改后会发生读取(尽管在现代操作系统上这是极不可能的),因为操作系统可能决定以不这样做的方式安排新的短期线程t 并行发生。

关于haskell - 共享 IORef 时,只要我使用atomicModifyIORef 写入,使用 readIORef 读取是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9328023/

相关文章:

java - hadoop DistributedFileSystem 线程安全吗?

haskell - ghci 中的 pretty-print

haskell - 尝试在 Haskell 中构造树

haskell - 实现 `Monad ((->) e)`

haskell - 使用动态函数更新多个集合的元素

Haskell IORef 数组使用

haskell - 什么时候可以使用 IORef?

haskell - 约束操作包

java - 为什么主线程被阻塞

objective-c - NSMutableString 线程安全?