Channel Synchronization in Haskell
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 doneTo run the program:
$ runhaskell channel-synchronization.hs
working...doneIf you removed the takeMVar done line from this program, the program would exit before the worker even started.
In this Haskell version:
- We use
MVarinstead of channels for synchronization. - The
forkIOfunction is used to start a new thread, similar to goroutines in Go. threadDelayis used to simulate work, similar totime.Sleepin Go.putMVaris used to send a signal, similar to sending on a channel in Go.takeMVaris 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.
Comments powered by Disqus