haskell - Cuándo/por qué usar un MVar sobre un TVar
shared-memory stm (2)
Creo que TVar es bastante fácil de usar, aunque MVar parece un poco más simple, mientras que TVar es un poco más funcional.
Entonces mi pregunta es bastante simple, ¿qué condición quiero que vaya a MVar en lugar de a TVar? Supongo que cada vez que no necesito una actualización transaccional puedo usar un MVar, pero ¿de qué manera me beneficia eso?
Los TVars son más seguros pero más lentos.
MVars puede estancarse, pero es mucho, mucho más eficiente.
Aún más eficiente es IORef
y atomicModifyIORef
(CAS), pero está muy restringido en lo que puede hacer con él.
Es realmente una seguridad sobre la compensación del rendimiento. Los TVars son completamente generales, muy seguros. Todo lo demás lo es menos, en una escala decreciente.
MVar
- puede estar vacío
- utilizado para implementar patrones de sincronización entre hilos
- permite la comunicación unidireccional entre hilos
- puede ser más rápido que
TVar
en algunos casos
TVar
- no puede estar vacío
- transacciones atómicas
- "memoria compartida" entre hilos; se puede usar para implementar, por ejemplo, un caché de búsqueda desde el cual varios hilos pueden leer / escribir
- el acceso es tiempo lineal en el número de operaciones en el registro de transacciones
- las transacciones de larga ejecución son vulnerables a la inanición si hay muchas transacciones más cortas, lo que les impide comprometerse con éxito
IORef
- referencia de puntero mutable
- a menudo utilizado para escrituras / actualizaciones de
IO
destructivas - tiene operaciones CAS atómicas, pero la lógica transaccional compleja es más adecuada para un
TVar
No existe una regla MVar
para usar MVar
vs TVar
, pero normalmente pienso si mi contenedor estará "vacío" MVar
( MVar
). ¿O tendré que realizar bloques atómicos de modificaciones en mi variable ( TVar
)?