GHC 在存在线程的情况下包含标准输出,但 GHCi 没有



我有下面的haskell程序

module Main where
import           Control.Concurrent
import           Control.Monad
import           GHC.IO.Handle
import           System.Process
unlessM :: Monad m => m Bool -> m () -> m()
unlessM cond m = do
c <- cond
unless c m
main :: IO ()
main = do
lock <- newMVar ()
void $ withCreateProcess
(proc exe args){ std_out = CreatePipe, std_err = CreatePipe }
$ handleProcess lock
where
exe = "/bin/bash"
args = ["-c", "echo 1; sleep 1; echo 2; sleep 1; echo 3 "]
handleProcess lock _ (Just outh) (Just errh) hand = do
_ <- forkIO $ showLines lock outh "STDOUT"
_ <- forkIO $ showLines lock errh "STDERR"
waitForProcess hand
handleProcess _ _ _ _ _ = fail "No output or error handlers"
showLines :: MVar () -> Handle -> String -> IO ()
showLines v h str =
unlessM (hIsClosed h) $
unlessM (hIsEOF h) $ do
l <- hGetLine h
() <- takeMVar v
putStrLn $ str ++ ": " ++ l
putMVar v ()
showLines v h str

使用ghci运行它可以提供预期的输出,但编译和运行不会产生任何

$ ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/drninjabatman/.ghci
Prelude> :load Main.hs
[1 of 1] Compiling Main             ( Main.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
STDOUT: 1
STDOUT: 2
STDOUT: 3
*Main> 
Leaving GHCi.
$ runhaskell ./Main.hs
STDOUT: 1
STDOUT: 2
STDOUT: 3
$ ghc Main.hs -o test
[1 of 1] Compiling Main             ( Main.hs, Main.o )
Linking test ...
$ ./test
$ # No output 

Haskell程序在其主线程停止时立即终止。

您需要将main修改为,以便在退出之前等待派生的线程。

在GHCi中,这不是一个问题,因为主线程运行REPL,所以它不会停止。

未测试的尝试:

handleProcess lock _ (Just outh) (Just errh) hand = do
lockOut <- newEmptyMVar
_ <- forkIO (showLines lock outh "STDOUT" >> putMVar lockOut ())
lockErr <- newEmptyMVar
_ <- forkIO (showLines lock errh "STDERR" >> putMVar lockErr ())
waitForProcess hand
takeMVar lockOut
takeMVar lockErr

最新更新