Title here
Summary here
In Haskell, we can use MVars for synchronization across threads. Here’s an example of using a blocking receive to wait for a thread to finish. When waiting for multiple threads to finish, you may prefer to use a similar mechanism to WaitGroup, which can be implemented using MVars.
import Control.Concurrent (forkIO, threadDelay, MVar, newEmptyMVar, putMVar, takeMVar)
import System.IO (hFlush, stdout)
-- This is the function we'll run in a separate thread. The
-- `done` MVar will be used to notify the main thread that
-- this function's work is done.
worker :: MVar Bool -> IO ()
worker done = do
putStr "working..."
hFlush stdout
threadDelay 1000000 -- Sleep for 1 second
putStrLn "done"
-- Send a value to notify that we're done.
putMVar done True
main :: IO ()
main = do
-- Create an empty MVar to use for synchronization
done <- newEmptyMVar
-- Start a worker thread, giving it the MVar to notify on.
forkIO $ worker done
-- Block until we receive a notification from the
-- worker on the MVar.
takeMVar done
To run the program:
$ runhaskell channel-synchronization.hs
working...done
If you removed the takeMVar done
line from this program, the program would exit before the worker
even started.
In this Haskell version:
MVar
instead of channels for synchronization.forkIO
function is used to start a new thread, similar to goroutines in Go.threadDelay
is used to simulate work, similar to time.Sleep
in Go.putMVar
is used to send a signal, similar to sending on a channel in Go.takeMVar
is used to wait for the signal, similar to receiving from a channel in Go.This example demonstrates how to use MVars in Haskell for basic thread synchronization, which is conceptually similar to using channels for goroutine synchronization in Go.