Advertisement
Guest User

Untitled

a guest
Apr 26th, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# LANGUAGE BangPatterns #-}
  2.  
  3. import Text.Printf
  4. import Control.Monad
  5. import Control.Concurrent
  6. import Control.Concurrent.QSem
  7.  
  8. nTasks = 10
  9. beginOffset = 10
  10.  
  11. fib x | x < 3 = 1
  12.       | otherwise = (fib $ x - 1) + (fib $ x - 2)
  13.  
  14. routine :: QSem -> (MVar Int, Int) -> IO ()
  15. routine outputMutex (resultMVar, x) = do
  16.     safeIOWithSem outputMutex $ printf "Thread id = %d start\n" x
  17.     let !result = fib x
  18.     putMVar resultMVar result
  19.     safeIOWithSem outputMutex $ printf "Thread id = %d end\n" x
  20.  
  21. safeIOWithSem :: QSem -> IO () -> IO ()
  22. safeIOWithSem m f = waitQSem m >> f >> signalQSem m
  23.  
  24. main :: IO ()
  25. main = do
  26.     outputMutex <- newQSem 1
  27.     resultMVars <- replicateM nTasks newEmptyMVar
  28.     let tasks = zip resultMVars [beginOffset .. beginOffset + nTasks]
  29.    
  30.     safeIOWithSem outputMutex $ getNumCapabilities >>= printf "Processors = %d\n"
  31.     safeIOWithSem outputMutex $ putStrLn "Start"
  32.    
  33.     mapM_ (forkIO . routine outputMutex) tasks
  34.    
  35.     forM_ tasks $ \(m, x) -> safeIOWithSem outputMutex $ takeMVar m >>= printf "Fib(%d) = %d\n" x
  36.    
  37.     safeIOWithSem outputMutex $ putStrLn "End"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement