MVar
es, como usted dijo, dirigido a multihebra, mientras que IORef
se puede usar como variable mutable en un único programa de subprocesos o como una construcción de sincronización en un programa multiproceso.
IORef
se puede utilizar junto con atomicModifyIORef
para obtener comparación y de intercambio en el comportamiento (CAS): los escritores y los lectores pueden sincronizar en un solo valor puro, almacenado en el IORef
. Los lectores usan readIORef
para leer un valor y los escritores usan atomicModifyIORef
para escribir un valor. Tenga en cuenta que atomicModifyIORef
no permite que los escritores realicen ningún efecto secundario dentro de la sección crítica (es decir, que solo pueden usar una función pura cuando cambien atómicamente el valor).
MVar
le permite implementar secciones críticas arbitrarias (usando withMVar
), que pueden tener efectos secundarios. También se pueden usar como un IORef
(como se describe en el párrafo anterior), pero a un costo mayor.
Si desea una intuición para qué tipo de semántica IORef
implementa su lo mismo que la semántica CAS Rich Hickey describe en una charla en el modelo de concurrencia de Clojure: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
Editar: Además, no se puede ejecutar en los puntos muertos usando IORef
(pero aún puede haber contención, lo que provoca reintentos).
MVars representan una abstracción tipo cola que puede tomar como máximo un elemento con semántica de bloqueo, mientras que un IORef siempre tiene un elemento en él. – hvr