并行IO导致终端中的随机文本输出

Yro*_*irg 4 parallel-processing concurrency haskell

我正在使用

import Control.Concurrent.ParallelIO.Global

main = parallel_ (map processI [1..(sdNumber runParameters)])  >> stopGlobalPool
Run Code Online (Sandbox Code Playgroud)

哪里

processI :: Int -> IO ()
Run Code Online (Sandbox Code Playgroud)

是一些函数,它从文件中读取数据,处理它并将其写入另一个文件.没有输出到终端.问题是当我运行程序时+RTS -N8终端充斥着随机文本之类的

piptufuht teata thtsieieo ocnsno e nscsdeoe qnqvuduee   ernvnstetiirioasanlil lolwynya. .s
w
a s s uY Ysosopuuue's'nvpvdeeee n dpdp rerdodoub beada
bub lel y
Run Code Online (Sandbox Code Playgroud)

怎么了?没有+ RTS就没有混乱.我无法使用更简单(适合在此处发布)的程序重现该行为.

GHC 7.0.3如果重要的话

Ada*_*ner 6

缓冲可能会阻止您构建一个简单的测试用例.我能够用它重现它(仅当使用+ RTS -Nsomething运行时):

import Control.Concurrent
import System.IO

main :: IO ()
main = do
    hSetBuffering stdout NoBuffering
    forkIO $ putStrLn "foo"
    forkIO $ putStrLn "bar"
    forkIO $ putStrLn "baz"
    threadDelay 1000    -- Allow things to print
Run Code Online (Sandbox Code Playgroud)

正如托马斯所提到的,你可能需要以某种方式对此进行排序,尽管我不确定如何直接写入文件会改变这一点.这是一个简单的例子,你可以用a来对它进行排序Chan.我确信有更好的方法可以做到这一点,这只是我如何得到这个没有输出的例子.

import Control.Concurrent
import Control.Concurrent.Chan
import System.IO

main :: IO ()
main = do
    hSetBuffering stdout NoBuffering

    ch <- newChan            -- Things written here are picked up by stuffWriter
    forkIO $ stuffWriter ch  -- Fire up concurrent stuffWriter

    forkIO $ writeChan ch "foo"
    forkIO $ writeChan ch "bar"
    forkIO $ writeChan ch "baz"
    threadDelay 1000         -- Allow things to print

-- | Write all the things!
stuffWriter :: Chan String -> IO ()
stuffWriter ch = do
    readChan ch >>= putStrLn -- Block, then write once I've got something
    stuffWriter ch           -- loop... looking for more things to write
Run Code Online (Sandbox Code Playgroud)

现在你对某个地方的写入现在是同步的(一次stuffWriter写一个东西),你应该没有更多的乱码.