<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">Hi everyone,<br><br>I have a beginer question on using MVar.<br><br>In the simple case I am getting what I expect...<br><br><br>***CODE***<br>module Main ( main ) where<br><br>import Control.Concurrent<br>import System.IO<br><br>main = do<br> mv <- newEmptyMVar<br> putMVar mv 'a'<br> threadDelay (5 * 10^6)<br> putMVar mv 'b'<br> threadDelay (5 * 10^6)<br>***/CODE***<br><br><br>Output after the first 5 second delay is :-<br><br>Demo.exe: thread blocked indefinitely<br><br><br><br>It even works as expected when there is a reading thread<br><br>***CODE***<br>module Main ( main ) where<br><br>import Control.Concurrent<br>import Control.Monad<br>import System.IO<br><br>main = do<br> mv <- newEmptyMVar<br> forkIO (readMV mv)<br> putMVar mv 'a'<br> threadDelay (5 * 10^6)<br> putMVar mv 'b'<br>
threadDelay (5 * 10^6)<br><br>readMV mv = forever $ do<br> ch <- takeMVar mv<br> putChar ch >> hFlush stdout<br>***/CODE***<br><br>Output including expected delays :-<br>ab<br><br><br><br>Then it starts to act unexpectedly<br><br>***CODE***<br>module Main ( main ) where<br><br>import Control.Concurrent<br>import Control.Monad<br>import System.IO<br><br>main = do<br> mv <- newEmptyMVar<br> forkIO (readMV mv)<br> putMVar mv 'a'<br> threadDelay (5 * 10^6)<br> putMVar mv 'b'<br> threadDelay (5 * 10^6)<br><br>readMV mv = forever $ do<br> ch <- modifyMVar mv modMV<br> putChar ch >> hFlush stdout<br> threadDelay (9*10^5)<br><br>modMV 'a' = return ('c','a')<br>modMV 'c' = return ('a','c')<br>modMV x = return (x,x)<br>***/CODE***<br><br>Output is :-<br>acacac<br><br><br>The problem is that the output stops after 5 seconds<br>and the program exits after 10 seconds. But
why?<br><br>Questions:-<br><br>1. Why does the output stop? (Shouldn't the reader thread<br>continue even if the main thread blocks on the second putMVar?)<br><br>2. Why does it exit? (Shouldn't it be blocked at the second<br>putMVar? The readMV thread now only modifies the MVar so it<br>should never be empty)<br><br>3. Is there a race condition using modifyMVar while there<br>is another thread blocked in a putMVar? (I am assuming the<br>second putMVar succeeded, but where did the 'b' go?)<br><br>Many thanks for any help<br><br>Adrian.</td></tr></table><br>