2016-08-18 59 views
3

停止主我有这样的代码:如何从终端

main = do 
    _ <- forkIO foo 
    _ <- forkIO bar 
    return() 

功能foobar启动,但只要main终止终止。我怎样才能让main无限期地运行,但没有做太多?

回答

10

async包很好地包装为concurrently foo bar

这是一个独立的stack shebang脚本。

#!/usr/bin/env stack 
{- stack 
    --resolver lts-6.12 
    --install-ghc 
    runghc 
    --package async 
-} 

import Control.Concurrent 
import Control.Concurrent.Async 

forever :: String -> Int -> IO() 
forever msg delay = loop 
    where 
    loop = do 
     putStrLn msg 
     threadDelay (delay * 1000) 
     loop 

foo = forever "foo" 3000 
bar = forever "bar" 5000 

main = foo `concurrently` bar 
5

你可以做的一件事就是使用MVar()作为一个简单的信号量。像

main = do 
    vFoo <- newEmptyMVar 
    vBar <- newEmptyMVar 
    forkIO (foo vFoo) 
    forkIO (bar vBar) 
    takeMVar vFoo 
    takeMVar vBar 

foo vFoo = do 
    ...whatever... 
    putMVar vFoo() 

bar vBar = do 
    ...whatever... 
    putMVar vBar() 
+0

甚至可能重用一个'MVar'。 'do {v < - newEmptyMVar; forkIO(foo >> putMVar v()); forkIO(bar >> putMVar v()); takeMVar v; takeMVar v}' –

+0

你也可以这样做,是的。它可能会略微增加编写错误的'takeMVar'调用次数的变化,或者让它不那么明显,为什么它们有这么多,但对于只有两个*线程,它可能没有问题。 – MathematicalOrchid

1

东西,你可以打电话给getChar所以你的主线程等待输入。这也将给你一个方便的方式来真正退出程序。或者,如果您不想要,只需在getChar上重复。

1

根据您想在这两个线程的一个失败的情况下什么样的行为,这可能是为async包一个很好的例子。

raceconcurrently这样的函数可能与您正在执行的操作特别相关。