Haskell concurrency IO behavior

I am trying to better understand concurrency in Haskell. I have the following code:

import Control.Concurrent main :: IO () main = do arr <- return $ [1..9] t <- newMVar 1 forkIO (takeMVar t >> (print.show) arr >> putMVar t 1) forkIO (takeMVar t >> (print.show) arr >> putMVar t 1) forkIO (takeMVar t >> (print.show) arr >> putMVar t 1) forkIO (takeMVar t >> (print.show) arr >> putMVar t 1) forkIO (takeMVar t >> (print.show) arr >> putMVar t 1) return () 

Sometimes I see print operations overlap and I get the following results (look at the second call):

 *Main Control.Concurrent> :l test.hs [1 of 1] Compiling Main ( test.hs, interpreted ) Ok, modules loaded: Main. *Main Control.Concurrent> main "[1,2,3,4,5,6,7,8,9]" "[1,2,3,4,5,6,7,8,9]" "[1,2,3,4,5,6,7,8,9]" "[1,2,3,4,5,6,7,8,9]" "[1,2,3,4,5,6,7,8,9]" *Main Control.Concurrent> main "[1,2,3,4,5,6,7,8,9]" "[1,2,3,4,5,6,7,8,9]" "[1,2,3,4,5,6,7,8,9]" ["[1,2,3,4,5,6,7,8,9]" ?"[1,2,3,4,5,6,7,8,9]" 1h*Main Control.Concurrent> 

I do not understand why this is happening. Using MVar for [1..9] also bad.

+4
source share
1 answer

Sometimes I see print operations overlap

The output sometimes overlaps because there is a lock on the standard output. Each thread causes a "print", which attempts to write one character, using a lock for each character. Due to the Haskell preemptive concurrency, you will see random interleaving of print threads.

If this is an undesirable behavior, instead, each thread sends the line that it wants to print to the printer stream, which in turn will produce serial line output.

+4
source

All Articles