No atomic read on MVar?
Philip K.F. Hölzenspies
p.k.f.holzenspies at utwente.nl
Mon Nov 3 06:29:04 EST 2008
I ran face first into an assumption I had made on MVar operations (in
Control.Concurrent); I had assumed there to be an atomic read (i.e.
non-destructive read, as opposed to destructive consume/take). The following
program illustrates what I had in mind.
testAtomic :: IO ()
testAtomic = do
var <- newMVar 0
forkIO (putMVar var 1 >> putStrLn "X")
r1 <- readMVar var
r2 <- takeMVar var
r3 <- takeMVar var
putStrLn("Result: " ++ show [r1,r2,r3])
If readMVar had been atomic, the result would be program termination with a
result of [0,0,1] being output. However, readMVar simply combines takeMVar
and putMVar, so the reading of r1 blocks after the takeMVar, because upon
taking the MVar, the blocked thread wakes up, puts 1 in var and prints X.
readMVar does not terminate for r1 (i.e. "1" is never printed).
I have now implemented my variable as a pair of MVars, one of which serves as
a lock on the other. Both for performance reasons and for deadlock analysis,
I would really like an atomic read on MVars, though. Does it exist? If not,
More information about the Glasgow-haskell-users