multithreading - Haskell forkIO threads writing on top of each other with putStrLn -


i playing around haskell lightweight threads (forkio) following code:

import control.concurrent  begintest :: io () begintest = go         go =         putstrln "very interesting string"         go         return ()  main =     threadid1 <- forkio $ begintest     threadid2 <- forkio $ begintest     threadid3 <- forkio $ begintest     threadid4 <- forkio $ begintest     threadid5 <- forkio $ begintest      let tid1 = show threadid1     let tid2 = show threadid2     let tid3 = show threadid3     let tid4 = show threadid4     let tid5 = show threadid5      putstrln "main thread"     putstrln $ tid1 ++ ", " ++ tid2 ++ ", " ++ tid3 ++ ", " ++ tid4 ++ ", " ++ tid5     getline     putstrln "done" 

now expected output whole bunch of these:

very interesting string interesting string interesting string interesting string 

with 1 of these somewhere in there:

main thread 

however, output (or first several lines anyway) turned out this:

very interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string interesting string vvvvimeeeenarrrrtiyyyyen    r iiiietnnnnshtttttreeeeierrrrnaeeeegdssss  ttttsiiiittnnnnrhggggir    nessssgatttt drrrriiiiivdnnnne ggggr5    y1 ,vvvvi eeeentrrrrthyyyyer    reiiiieannnnsdtttttieeeeidrrrrn eeeeg5ssss 2tttts,iiiit nnnnrtggggih    nrssssgetttt arrrrdiiiivinnnnedggggr     y5 3vvvvi,eeeen rrrrttyyyyeh    rriiiieennnnsatttttdeeeeiirrrrndeeeeg ssss 5tttts4iiiit,nnnnr ggggit    nhssssgrtttt errrraiiiivdnnnneiggggrd    y  5vvvvi5eeeen rrrrtyyyye    riiiiennnnsttttteeeeirrrrneeeegssss ttttsiiiitnnnnrggggi    nssssgtttt rrrriiiivnnnneggggr    y vvvvieeeenrrrrtyyyye    riiiiennnnsttttteeeeirrrrneeeegssss ttttsiiiitnnnnrggggi    nssssgtttt rrrriiiivnnnneggggr 

every few lines text shift, though it's pretty clear very interesting strings ended on top of each other, because somehow threads using putstrln @ same time ended writing stdout on top of each other. why this, , how (without resorting message passing, timing, or other overcomplicated , convoluted solution) can overcome?

simply put, putstrln not atomic operation. every character may interleaved other different thread.

(i not sure whether in multi-byte encodings such utf8 guaranteed multi-byte character atomically handled.)

if want atomicity, can use shared mutex e.g.

do lock <- newmvar ()    let atomicputstrln str = takemvar lock >> putstrln str >> putmvar lock ()    forkio $ forever (atomicputstrln "hello")    forkio $ forever (atomicputstrln "world") 

as suggested in comments below, can simplify , make above exception-safe follows:

do lock <- newmvar ()    let atomicputstrln str = withmvar lock (\_ -> putstrln str)    forkio $ forever (atomicputstrln "hello")    forkio $ forever (atomicputstrln "world") 

Comments

Popular posts from this blog

php - Admin SDK -- get information about the group -

dns - How To Use Custom Nameserver On Free Cloudflare? -

Python Error - TypeError: input expected at most 1 arguments, got 3 -