[Haskell-cafe] readMVar and the devils

Conor T McBride c.t.mcbride at durham.ac.uk
Fri Jul 2 05:15:57 EDT 2004

Hi folks

I'm having a play with Concurrent Haskell, and came across this in the

   readMVar :: MVar a -> IO a
   This is a combination of takeMVar and putMVar; ie. it takes the value
   from the MVar, puts it back, and also returns it.

I was just wondering if I understand things correctly. Suppose myMVar
is nonempty and I have one thread executing

   do x <- takeMVar myMVar      -- (A)
      putMVar myMVar x          -- (B)
      return x

and another executing

   putMVar myMVar y             -- (C)


(1) Is it possible that an evil scheduler will execute (A) then (C)
       and block on (B)?

(2) Is it the case that if myMVar is nonempty and readMVar is chosen
       for execution, that readMVar myMVar takes the value
       from myMVar, guaranteed that the _same_ value will be put
       back immediately, and also returned?

(3) If yes to both, what combination of takeMVar and putMVar manages
       to maintain the lock in between the two?

I'm only asking, because I'm trying to cook up some kind of partial
evaluator for programs which are being simultaneously edited by
fiercely argumentative devils. Kind of `demonic laziness', where
the computations decide when _they_ feel like running (eg sometime after
the program turns up), rather than the `angelic laziness' we're used to.
I'd like to use MVars in a write-once-read-many style, so that once
someone fills in a bit of program, it stays put. I'd hate for another
devil to sneak in a replacement program just in the twinkling of an eye
between taking something out to read and putting it back to be read again.

I guess I could use some kind of extra semaphore MVar to ensure that
the reader has the lock on the program MVar, but that's more like
hard work. Is readMVar what I want?

Another more general question would be `is this an utterly stupid
thing to do in practice?'. I mean, just consider an evaluator for
some simple language (eg arithmetic expressions), implemented by forking
a thread for every subcomputation, and using MVars to transmit the
values. Is that diabolically slow compared to a normal evaluator? I
guess I'll try it, but I was wondering if anyone had any useful
experience to share?



More information about the Haskell-Cafe mailing list