Loading try5.hs +60 −13 Original line number Diff line number Diff line -- use default Chan, use shutdown msg to terminate program. -- let master thread wait for all created threads to finish. -- well, do that on try 1 as well. import Control.Concurrent (threadDelay) import Control.Monad import Control.Concurrent.MVar import Control.Concurrent import Text.Printf import System.Random import WorkGroup -- | delay many seconds, then print a msg printMsg :: Int -> IO () printMsg sec = do threadDelay $ sec * 1000000 putStrLn "hehe" data Message a = Shutdown | Payload a fuzzDelay = False fuzz :: IO () fuzz = if fuzzDelay then do seconds <- (getStdRandom random :: IO Double) threadDelay $ round (realToFrac (1000000 * seconds)) else return () -- handleShutdown :: Message a -> (a -> IO ()) -> IO () -- handleShutdown Shutdown _ = return () -- handleShutdown (Payload x) f = f x counterManager :: MVar Integer -> Chan (Message Integer) -> Chan (Message [String]) -> IO () counterManager counter counterCh printerCh = do fuzz msg <- readChan counterCh case msg of Shutdown -> return () Payload incrementBy -> do fuzz newCount <- modifyMVar counter (\i -> return (i + incrementBy, i + incrementBy)) fuzz writeChan printerCh $ Payload [printf "The count is %d" newCount, "---------------"] fuzz counterManager counter counterCh printerCh printerManager :: Chan (Message [String]) -> IO () printerManager ch = do fuzz msg <- readChan ch case msg of Shutdown -> return () Payload rows -> do fuzz mapM_ putStrLn rows fuzz printerManager ch main :: IO () main = do wg <- newWorkGroup forkIOwg wg $ printMsg 1 forkIOwg wg $ printMsg 2 forkIOwg wg $ printMsg 3 forkIOwg wg $ printMsg 4 joinWorkGroup wg counter <- newMVar 0 counterCh <- newChan printerCh <- newChan counterWg <- newWorkGroup forkIOwg counterWg $ counterManager counter counterCh printerCh printerWg <- newWorkGroup forkIOwg printerWg $ printerManager printerCh writeChan printerCh $ Payload ["Starting up"] replicateM_ 10 (writeChan counterCh $ Payload 1) writeChan counterCh Shutdown joinWorkGroup counterWg writeChan printerCh $ Payload ["Finishing up"] writeChan printerCh Shutdown joinWorkGroup printerWg Loading
try5.hs +60 −13 Original line number Diff line number Diff line -- use default Chan, use shutdown msg to terminate program. -- let master thread wait for all created threads to finish. -- well, do that on try 1 as well. import Control.Concurrent (threadDelay) import Control.Monad import Control.Concurrent.MVar import Control.Concurrent import Text.Printf import System.Random import WorkGroup -- | delay many seconds, then print a msg printMsg :: Int -> IO () printMsg sec = do threadDelay $ sec * 1000000 putStrLn "hehe" data Message a = Shutdown | Payload a fuzzDelay = False fuzz :: IO () fuzz = if fuzzDelay then do seconds <- (getStdRandom random :: IO Double) threadDelay $ round (realToFrac (1000000 * seconds)) else return () -- handleShutdown :: Message a -> (a -> IO ()) -> IO () -- handleShutdown Shutdown _ = return () -- handleShutdown (Payload x) f = f x counterManager :: MVar Integer -> Chan (Message Integer) -> Chan (Message [String]) -> IO () counterManager counter counterCh printerCh = do fuzz msg <- readChan counterCh case msg of Shutdown -> return () Payload incrementBy -> do fuzz newCount <- modifyMVar counter (\i -> return (i + incrementBy, i + incrementBy)) fuzz writeChan printerCh $ Payload [printf "The count is %d" newCount, "---------------"] fuzz counterManager counter counterCh printerCh printerManager :: Chan (Message [String]) -> IO () printerManager ch = do fuzz msg <- readChan ch case msg of Shutdown -> return () Payload rows -> do fuzz mapM_ putStrLn rows fuzz printerManager ch main :: IO () main = do wg <- newWorkGroup forkIOwg wg $ printMsg 1 forkIOwg wg $ printMsg 2 forkIOwg wg $ printMsg 3 forkIOwg wg $ printMsg 4 joinWorkGroup wg counter <- newMVar 0 counterCh <- newChan printerCh <- newChan counterWg <- newWorkGroup forkIOwg counterWg $ counterManager counter counterCh printerCh printerWg <- newWorkGroup forkIOwg printerWg $ printerManager printerCh writeChan printerCh $ Payload ["Starting up"] replicateM_ 10 (writeChan counterCh $ Payload 1) writeChan counterCh Shutdown joinWorkGroup counterWg writeChan printerCh $ Payload ["Finishing up"] writeChan printerCh Shutdown joinWorkGroup printerWg