Question on concurrency

Hello Haskellers, Having been pretty much impressed by Don Stewart's "Practical Haskell" (http://donsbot.wordpress.com/2010/08/17/practical-haskell/), I started to write a Haskell script to run maven jobs (yes, I know...). In the course of undertaking this fantastic endeavour, I started to use the System.Process.readProcessWithExitCode function, but following the advice in the comment for this function, I rolled my own stuff and ended up writing the following:
doRunMvnInIO pom args filters e = do (Just inh, Just outh, Just errh, pid) <- createProcess (proc (maven e) (["-f", pom] ++ args)) { std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe } waitQ <- newEmptyMVar
mapM (printAndWait waitQ) [outh, errh]
hClose inh -- wait on the process waitForProcess pid where printAndWait waitQ hdl = do out <- hGetContents hdl forkIO (mapM (putStrLn) (filter filters $ lines out) >> putMVar waitQ ()) takeMVar waitQ hClose hdl
This is actually a rewrite of the following function:
doRunMvnInIO' pom args filters e = do (Just inh, Just outh, Just errh, pid) <- createProcess (proc (maven e) (["-f", pom] ++ args)) { std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe } waitQ <- newEmptyMVar
mapM (printAndWait waitQ) [outh, errh] >>= mapM (\_ -> takeMVar waitQ)
hClose inh hClose outh hClose errh -- wait on the process waitForProcess pid where printAndWait waitQ hdl = do out <- hGetContents hdl forkIO (mapM (putStrLn) (filter filters $ lines out) >> putMVar waitQ ())
What surprised me is that I would expect the behaviour of the two functions to be different: - in doRunMvnInIO, I would expect stdout's content to be printed before stderr, ie. the 2 threads are ordered because I call takeMVar in between calls to forkIO - in doRunMvnInIO', this is not true and both theads run concurrently. but actually there does not seem to be a difference: printing is still interleaved in both functions, AFAICT. I would welcome any help on this. Best regards, Arnaud

On 14/09/10 07:45, Arnaud Bailly wrote:
What surprised me is that I would expect the behaviour of the two functions to be different: - in doRunMvnInIO, I would expect stdout's content to be printed before stderr, ie. the 2 threads are ordered because I call takeMVar in between calls to forkIO - in doRunMvnInIO', this is not true and both theads run concurrently.
but actually there does not seem to be a difference: printing is still interleaved in both functions, AFAICT.
Hi, I've tried your code (substituting a program that spits out different streams of numbers on stdout and stderr for maven), and I see the behaviour you had expected: the first version does print all of stdout before stderr, whereas the second version shows interleaving of the two streams. Are you certain that you are seeing interleaving in the first version? Thanks, Neil.

Probably did not test enough. Sorry for the noise.
arnaud
On Tue, Sep 14, 2010 at 12:18 PM, Neil Brown
On 14/09/10 07:45, Arnaud Bailly wrote:
What surprised me is that I would expect the behaviour of the two functions to be different: - in doRunMvnInIO, I would expect stdout's content to be printed before stderr, ie. the 2 threads are ordered because I call takeMVar in between calls to forkIO - in doRunMvnInIO', this is not true and both theads run concurrently.
but actually there does not seem to be a difference: printing is still interleaved in both functions, AFAICT.
Hi,
I've tried your code (substituting a program that spits out different streams of numbers on stdout and stderr for maven), and I see the behaviour you had expected: the first version does print all of stdout before stderr, whereas the second version shows interleaving of the two streams. Are you certain that you are seeing interleaving in the first version?
Thanks,
Neil.
participants (2)
-
Arnaud Bailly
-
Neil Brown