[Haskell-cafe] Question on concurrency

Arnaud Bailly arnaud.oqube at gmail.com
Tue Sep 14 02:45:41 EDT 2010


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


More information about the Haskell-Cafe mailing list