1

在摇动中使用并行构建时,我得到如下格式错误的输出:

[»] Compiling src/Game/Game.cpp
[»] Compiling [»] Compiling [»] Compiling src/Graphics/Image/Png/PngLoader.cpp
src/Main.cpp
src/System/HeartBeat.cpp
[»] Compiling src/Window/Window.cpp
[»] Compiling src/Window/GlfwContext.cpp

我想这是我打印的某种同步问题。我应该注意,我使用以下命令作为输出命令:

shakeOutput = const $ BS.putStr . BS.pack

我的规则的状态消息打印部分如下所示:

liftIO $ setSGR [SetColor Foreground Vivid Green]
putNormal "[\175] Compiling "
liftIO $ setSGR [SetColor Foreground Vivid Yellow]
putNormal $ c ++ "\n"
liftIO $ setSGR [Reset]

有没有办法避免我的输出内置抖动出现这种打印问题?如果不知道打印代码在抖动规则内,则适合使用哪种 haskell 同步方法?

4

2 回答 2

1

shakeOutput默认的原因const $ BS.putStr . BS.pack是因为它BS.putStr需要 Haskell 控制台锁,从而确保输出不会交错。我不认为这是对 的合同保证BS.putStr,但如果它不再如此,我将shakeOutput默认添加一个锁定。有两种方法可以解决该问题:

添加锁

一种方法是添加一个锁,理想情况下是一个租用互斥锁(我已经在 Haskell 中见过,但可以相对容易地在MVarand之上合成myThreadId)。然后您shakeOutput获取锁,并且在您shakeOutput多次调用的代码段中,您还可以在整个块周围获取锁。Mutex 可能希望存储在顶级unsafePerformIOCAF 中。

使用单个shakeOutput呼叫

由于shakeOutput已经是原子的,您可以通过将代码重写为来重用该属性:

putNormal $
    setSGRCode [SetColor Foreground Vivid Green] ++
    "[\175] Compiling " ++
     setSGRCode [SetColor Foreground Vivid Yellow] ++
     c ++ "\n" ++
     setSGRCode [Reset]

我鼓励第二种方法,因为它更简单,并且还确保如果将详细程度变为安静,代码仍然不会被打印。

于 2015-11-13T13:34:33.540 回答
0

我的方法是使用资源:

con <- newResource "Console" 1
let withConsole = withResource con 1 . liftIO
于 2016-02-20T15:41:32.800 回答