Поведение параллелизма в Хаскеле - PullRequest
4 голосов
/ 15 августа 2010

Я пытаюсь глубже понять параллелизм в Хаскеле.У меня есть следующий код:

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 ()

Иногда я вижу, что операции печати перекрываются, и я получаю следующие результаты (посмотрите на второй вызов):

*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> 

Я не понимаюпочему это происходит.Использование MVar для [1..9] тоже плохо работает.

1 Ответ

4 голосов
/ 15 августа 2010

Иногда я вижу, что операции печати перекрываются

Выход иногда перекрывается, потому что на стандартном выходе есть блокировка. Каждый поток вызывает «печать», которая пытается выписать один символ, взяв блокировку для каждого символа. Из-за преимущественного параллелизма в Haskell вы увидите случайное чередование печати потоков.

Если это нежелательное поведение, вместо этого пусть каждый поток отправляет строку, которую он желает распечатать, в поток принтера, который, в свою очередь, выполняет последовательный построчный вывод.

...