Question

I find TVar's quite easy to work with even though MVar's appear a little simpler, while TVar's a little more featureful.

So my question is pretty simple, what condition do I want to go to MVar rather than TVar? I suppose anytime I don't need transactional update I can use an MVar, but in what way does that benefit me?

Was it helpful?

Solution 2

TVars are safer but slower.

MVars can deadlock, but are much, much more efficient.

More efficient still is IORef and atomicModifyIORef (CAS), but that's highly restricted in what you can do with it.

It's really a safety over performance trade off. TVars are fully general, very safe. Everything else is less so, on a decreasing scale.

OTHER TIPS

MVar

  • can be empty
  • used to implement synchronization patterns between threads
  • allows one-way communication between threads
  • can be faster than TVar in some cases

TVar

  • can not be empty
  • atomic transactions
  • "shared memory" between threads; can be used to implement, for example, a lookup cache from which multiple threads can read/write
  • access is linear time in the number of operations in the transaction log
  • long running transactions are vulnerable to starvation if there are many shorter transactions, preventing them from commiting successfully

IORef

  • mutable pointer-like reference
  • often used for destructive IO writes/updates
  • has atomic CAS operations, but complex transactional logic is better suited to a TVar

There is not really a hard and fast rule for when to use MVar or TVar. If the resource I'm guarding will ever be "missing" (as opposed to empty, consider Nothing vs Just mempty), then MVar often makes the most sense. If I will need to perform atomic blocks of modifications to the resource, then TVar is most suitable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top