Skip to content

Instantly share code, notes, and snippets.

@AndrasKovacs
Last active December 16, 2015 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrasKovacs/5466213 to your computer and use it in GitHub Desktop.
Save AndrasKovacs/5466213 to your computer and use it in GitHub Desktop.
Dining philosophers solution with STM.
import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM
import System.Random
import Text.Printf
philosophers = ["Aristotle", "Kant", "Spinoza", "Marx", "Russel"]
waitSome = randomRIO (1000, 5000) >>= threadDelay . (*1000)
runPhilo :: String -> (TMVar Int, TMVar Int) -> IO ()
runPhilo name (l, r) = forever $ do
printf "%s is waiting for the forks.\n" name
[lFork, rFork] <- atomically $ mapM takeTMVar [l, r]
printf "%s is eating with forks %d and %d.\n" name lFork rFork
waitSome
atomically $ zipWithM_ putTMVar [l, r] [lFork, rFork]
printf "%s is thinking.\n" name
waitSome
main = do
printf "Press enter to end dinner.\n\n"
forks <- mapM newTMVarIO [1..5]
zipWithM_ ((forkIO.) . runPhilo) philosophers (ap zip (tail . cycle) forks)
getLine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment