如何避免并行构建中的输出同步问题?
How to avoid output synchronization problems in parallel builds?
在 shake 中使用并行构建时,我得到如下格式错误的输出:
[»] 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 "[5] Compiling "
liftIO $ setSGR [SetColor Foreground Vivid Yellow]
putNormal $ c ++ "\n"
liftIO $ setSGR [Reset]
有没有办法避免我在 shake 中内置的输出出现这种打印问题?如果不是的话,哪种haskell同步方法适合使用,知道打印代码在抖动规则内?
shakeOutput
默认为 const $ BS.putStr . BS.pack
的原因是因为 BS.putStr
获取了 Haskell 控制台锁,从而确保输出不会交错。我不认为这是 BS.putStr
的合同保证,但如果它不再如此,我将默认在 shakeOutput
周围添加一个锁。有两种方法可以解决此问题:
加一把锁
一种方法是添加一个锁,最好是一个 renterant Mutex(不是我在 Haskell 中看到的东西,但可以相对容易地在 MVar
和 [=17 之上合成=]).然后你让 shakeOutput
获得锁,并且在多次调用 shakeOutput
的代码片段中你也获得了整个块的锁。 Mutex 可能希望存储在顶级 unsafePerformIO
CAF 中。
使用单个 shakeOutput
调用
因为 shakeOutput
已经是原子的,你可以通过重写你的代码来重用 属性:
putNormal $
setSGRCode [SetColor Foreground Vivid Green] ++
"[5] Compiling " ++
setSGRCode [SetColor Foreground Vivid Yellow] ++
c ++ "\n" ++
setSGRCode [Reset]
我鼓励第二种方法,因为它更简单,并且还确保如果将冗长变成安静,代码仍然不会被打印出来。
我的方法是使用资源:
con <- newResource "Console" 1
let withConsole = withResource con 1 . liftIO
在 shake 中使用并行构建时,我得到如下格式错误的输出:
[»] 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 "[5] Compiling "
liftIO $ setSGR [SetColor Foreground Vivid Yellow]
putNormal $ c ++ "\n"
liftIO $ setSGR [Reset]
有没有办法避免我在 shake 中内置的输出出现这种打印问题?如果不是的话,哪种haskell同步方法适合使用,知道打印代码在抖动规则内?
shakeOutput
默认为 const $ BS.putStr . BS.pack
的原因是因为 BS.putStr
获取了 Haskell 控制台锁,从而确保输出不会交错。我不认为这是 BS.putStr
的合同保证,但如果它不再如此,我将默认在 shakeOutput
周围添加一个锁。有两种方法可以解决此问题:
加一把锁
一种方法是添加一个锁,最好是一个 renterant Mutex(不是我在 Haskell 中看到的东西,但可以相对容易地在 MVar
和 [=17 之上合成=]).然后你让 shakeOutput
获得锁,并且在多次调用 shakeOutput
的代码片段中你也获得了整个块的锁。 Mutex 可能希望存储在顶级 unsafePerformIO
CAF 中。
使用单个 shakeOutput
调用
因为 shakeOutput
已经是原子的,你可以通过重写你的代码来重用 属性:
putNormal $
setSGRCode [SetColor Foreground Vivid Green] ++
"[5] Compiling " ++
setSGRCode [SetColor Foreground Vivid Yellow] ++
c ++ "\n" ++
setSGRCode [Reset]
我鼓励第二种方法,因为它更简单,并且还确保如果将冗长变成安静,代码仍然不会被打印出来。
我的方法是使用资源:
con <- newResource "Console" 1
let withConsole = withResource con 1 . liftIO