I'm interested in Haskell programming, but I'd want to create a job pool system, and I wonder if that will be a problem in Haskell.
Below is a simple program in Ruby. On one thread of execution, words are taken from a user and added to a list. On another thread, words are taken from the list and processed in some way (in this case, reversed and printed back to the user).
words = []
# Create new thread to take words from array, one at a time, and process them
t = Thread.new {
loop do
unless words.empty?
word = words.pop
break if word == 'quit'
sleep 1
puts word.reverse
end
end
}
# Take words from user and add to array
loop do
puts "Enter word:"
word = gets.chomp
words << word
break if word == 'quit'
end
t.join
What is the equivalent Haskell code?
Here's a pretty close translation.
Chan
is a FIFO queue for message passing between Haskell threads.
Below I use a MVar
for waiting that the spooler has exited. This is like a regular mutable variable, but it is protected with a mutex. It can either be empty (only a put
is allowed, take
s wait) or full (only a take
is allowed, put
s wait).
I also use Haskell threads below, which might be run on separate OS-level threads or not -- the Haskell runtime chooses that. Haskell threads are very cheap, compared with OS threads.
See e.g. Real World Haskell for more discussion.
{-# OPTIONS -Wall #-}
module JobPool where
import Control.Monad (when)
import Control.Concurrent
spooler :: Chan String -> MVar () -> IO ()
spooler ch stop = do
word <- readChan ch
if word == "quit"
then putMVar stop ()
else do
threadDelay 1000000 -- us
putStrLn (reverse word)
spooler ch stop
main :: IO ()
main = do
stop <- newEmptyMVar
ch <- newChan
_ <- forkIO $ spooler ch stop
let loop = do
word <- getLine
writeChan ch word
when (word /= "quit") loop
loop
takeMVar stop