Reputation: 11307
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
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
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
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
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