如何停止 main 函数终止

3

我有这段代码:

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

函数 foobar 开始运行,但只要 main 终止,它们就会终止。我该如何让 main 无限期地运行,但不做太多事情呢?

4个回答

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 ()

不妨甚至可以重复使用单个MVardo { v <- newEmptyMVar; forkIO (foo >> putMVar v ()); forkIO (bar >> putMVar v ()); takeMVar v; takeMVar v } - Daniel Wagner
是的,你也可以这样做。这可能会稍微增加写入错误数量的 takeMVar 调用或使其不太明显的可能性,但对于仅有的 两个 线程来说,这应该没问题。 - MathematicalOrchid

1

根据您想要的行为,如果其中一个线程失败,这可能是async包的一个好例子。

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


1
你可以调用 getChar 使主线程等待输入。这也为你提供了一个方便的方法来真正退出程序。或者如果你不想那样做,只需在 getChar 上进行递归即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接