zoran119
zoran119

Reputation: 11307

How to stop main from terminating

I have this code:

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

Functions foo and bar start, but terminate as soon as main terminates. How can I keep main running indefinitely, but not doing much?

Upvotes: 3

Views: 318

Answers (4)

glguy
glguy

Reputation: 1090

Depending on what behavior you want in the case that one of the two threads fails, this could be a good case for the async package.

Functions like race and concurrently might be particularly relevant to what you're doing.

Upvotes: 1

Steven Shaw
Steven Shaw

Reputation: 6249

The async package nicely wraps this up as concurrently foo bar.

Here's a self-contained stack shebang script.

#!/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

Upvotes: 10

Mo.
Mo.

Reputation: 15343

You could call getChar so your main thread waits for input. This would also give you a convenient way to really exit the program. Or if you don't want that, just recur on the getChar.

Upvotes: 1

MathematicalOrchid
MathematicalOrchid

Reputation: 62818

One thing you could do is to use an MVar () as a simple semaphore. Something like

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

Upvotes: 5

Related Questions