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
... нет никакой гарантии, что чтение произойдет после изменения (хотя это крайне маловероятно для современных ОС), потому что операционная система может решить запланировать новый недолговечный поток таким образом, что это может происходить параллельно.