MVar
, как вы сказали, предназначен для многопоточности, в то время как IORef
может использоваться как изменяемая переменная в однопоточной программе или как конструкция синхронизации в многопоточной программе.
IORef
может использоваться вместе с atomicModifyIORef
для получения поведения сравнения и замены (CAS): писатели и читатели могут синхронизироваться по одному чистому значению, хранящемуся в IORef
.Читатели используют readIORef
для чтения значения, а писатели используют atomicModifyIORef
для записи значения.Обратите внимание, что atomicModifyIORef
не позволяет авторам выполнять какие-либо побочные эффекты внутри критической секции (то есть они могут использовать чистую функцию только при атомарном изменении значения).
MVar
позволяет реализовать произвольные критические секции(используя withMVar
), который может содержать побочные эффекты.Они также могут использоваться точно так же, как IORef
(как описано в предыдущем абзаце), но с более высокой стоимостью.
Если вы хотите, чтобы интуиция для того, какой тип семантики IORef
реализует ее так же, какСемантика CAS, которую Rich Hickey описывает в своем выступлении о модели параллелизма Clojure: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
Редактировать: Кроме того, вы не можете столкнуться с тупиками, используя IORef
(но все еще может быть конфликт, вызывающий повторные попытки).