MVars
concurrencyicon.icon
MVars
An MVar a is mutable location that is either empty or contains a value of type a .
It has two fundamental operations:
putMVar :: MVar a -> a -> IO() which fills an MVar if it is empty and blocks otherwise, and
takeMVar :: MVar a -> IO a which empties an MVar if it is full and blocks otherwise.
They can be used in multiple different ways:
as synchronized mutable variables,
as channels, with takeMVar and putMVar as receive and send, and
as a binary semaphore MVar () , with takeMVar and putMVar as wait and signal.
Applicability of MVars
MVar s offer more flexibility than IORef s, but less flexibility than TVars.
They are appropriate for building synchronization primitives and performing simple interthread communication;
however they are very simple and susceptible to race conditions, deadlocks or uncaught exceptions.
Do not use them if you need to perform larger atomic operations such as reading from multiple variables: Use
TVar s instead.
MVar fairness guarantee
No thread can be blocked indefinitely on an MVar unless another thread holds that MVar indefinitely.
One usual implementation of this fairness guarantee is that threads blocked on an MVar are served in a first-in-first-out fashion, but this is not guaranteed in the semantics.
TVar s do not give the same guarantee.
code:MVar.hs
newEmptyMVar :: IO (MVar a)
newMVar :: a -> IO (MVar a)
putMVar:: MVar a -> a -> IO()
takeMVar :: MVar a -> IO a
readMVar :: MVar a -> IO a
tryPutMVar :: MVar a -> a -> IO Bool
tryTakeMVar :: MVar a -> IO (Maybe a)
tryReadMVar :: MVar a -> IO (Maybe a)
modifyMVar::MVar a->(a->IO (a,b))->IO b
withMVar::MVar a-> (a -> IOb) -> IO b