10

IORef複数のスレッド間で共有し、atomicModifyIORefそれに書き込むために使用する場合:

atomicModifyIORef ref (\_ -> (new, ()))

プレーンオールドで値を読み取っても安全readIORefですか? または、変更readIORef後に別のスレッドで古い値を返す可能性はありatomicModifyIORefますか?

それがドキュメントが意味することだと思います:

atomicModifyIORef は、並べ替えに対するバリアとして機能します。複数のatomicModifyIORef操作は、厳密なプログラム順序で発生します。atomicModifyIORef は、以前の (プログラムの順序で) IORef 操作の前、または後の IORef 操作の後に発生することはありません。

確認したいだけです。

4

3 に答える 3

14

atomicModifyIORefアトミック読み取りと次のアトミック書き込みの間に何も起こらないことを保証し、操作全体をアトミックにします。あなたが引用したコメントは、atomicModifyIORefs が並行して発生することはなく、オプティマイザーはプログラムを最適化するためにステートメントを並べ替えようとしないことを示しています (場合によっては、個別の読み取りと書き込みを安全に移動できます。たとえばa' <- read a; b' <- read b; write c $ a' + b'、読み取りは安全に並べ替えることができます)

readIORef1 つの操作しか実行しないため、既にアトミックです。

ただし、別の問題について話し合っています。はい。atomicModify_ t=3ms_ read_ t=4msでも; スレッドは並行して実行されることが保証されていないため、実行する場合 (疑似コード):

forkIO $ do
  sleep 100 ms
  atomicModify
sleep 1000 ms
read

...変更後に読み取りが行われるという保証はありません (ただし、最新の OS ではほとんどありません)。平行。

于 2012-02-17T12:27:15.830 に答える
2

基本的に何の保証も与えないので、複数のスレッドで IORef を使用したくありません。私は通常、代わりに MVar を使用します。

于 2012-02-17T13:10:11.007 に答える
2

複数のスレッド間で変更可能な参照を共有したい場合は、TVar代わりにIORef. 結局のところ、それが TVars の全体的な動機です。TVar は IORef とほぼ同じ方法で使用しますが、アクセスまたは変更は、atomically常にアトミック操作であることが保証されているブロック内に含める必要があります。

于 2012-02-17T13:02:28.120 に答える