Intro to
Concurrent
Haskell
Sean Hagstrom
Intro to
Concurrent
Haskell
Haskell
Haskell
Pure
Typed
Lazy
-- module imports
import Control.Concurrent
-- function definition
add a b = a + b
-- function definition with type annotations
add :: Int -> Int -> Int
add a b = a + b
-- main of program
main :: IO ()
main = putStrLn "Hello"
-- main of program with more sugar
main :: IO ()
main = do
putStrLn "Hello"
putStrLn "World"
Haskell
Threads
Threads
Process
Thread #1
Thread #2
Haskell Threads
Green
Preemptive
import Control.Concurrent
import Control.Monad
import System.IO
sleep = threadDelay . (10^6 *)
main = do
hSetBuffering stdout NoBuffering
forkIO $ forever $ putChar 'A'
forkIO $ forever $ putChar 'B'
sleep 1
$ runhaskell threads.hs | tail -c 100
ABABABABABABABABABABABABABABABABABABABABABABABABAB ABABABABABABABABABABABABABABABABABABABABABABABBBBB
Haskell
Threads
IORefs
IORefs
Mutable
IO Only
import Control.Concurrent
import Control.Monad
import Data.IORef
sleep = threadDelay . (10^6 *)
main = do
counter <- newIORef 0
forkIO $ forever $ do
modifyIORef' counter (+1)
sleep 1
forever $ do
sleep 1
readIORef counter >>= putStr . show
$ runhaskell iorefs.hs
2
3
4
5
5
Haskell
Threads
MVars
IORefs
MVars
Mutable
Locking
Fair
MVar
Value
Value
Value
Value
Value
Value
import Control.Concurrent
import Control.Concurrent.MVar
main = do
mvar <- newEmptyMVar
forkIO $ do
putMVar mvar 'a'
char <- takeMVar mvar
print char
$ runhaskell mvars.hs
'a'
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Monad
sleep = threadDelay . (10^6 *)
main = do
counter <- newMVar 0
forkIO $ forever $ do
count <- takeMVar counter
sleep 1
putMVar counter $! count + 1
forever $ do
withMVar counter (putStr . show)
1
2
3
4
5
$ runhaskell mvars-counter.hs
1
2
3
4
5
Channels
Haskell
Threads
MVars
IORefs
Channels
Buffered
Unbounded
Async
Channel
Read
Write
Stream
import Control.Concurrent
import Control.Concurrent.Chan
import Control.Monad
subscriber chan = do
newChan <- dupChan chan
forever $ do
putChar =<< readChan newChan
main = do
chan <- newChan
forkIO $ subscriber chan
forkIO $ subscriber chan
writeChan chan 'a'
writeChan chan 'b'
$ runhaskell channels.hs
a
a
b
b
import Control.Concurrent
import Control.Concurrent.Chan
import Control.Monad
import Data.IORef
sleep = threadDelay . (10^6 *)
publisher chan = do
counter <- newIORef 0
forever $ do
count <- fmap (+1) $ readIORef counter
writeChan chan count
writeIORef counter count
sleep 1
main = do
chan <- newChan
forkIO $ publisher chan
forever $ readChan chan >>= (putStr . show)
$ runhaskell channels-counter.hs
1
2
3
4
5
Channels
Haskell
Threads
MVars
IORefs
Channels
Async
STM
GHC
More?
Concurrent Haskell
Resources
by Simon Marlow
Reliable Concurrency Without the Actor Model
by Andrew Rademacher
Parallel and Concurrent Programming in Haskell
by Simon Marlow
chimera.labs.oreilly.com/books/1230000000929
youtube.com/watch?v=8OQUH8q4sMM
www.infoq.com/presentations/Concurrent-Haskell
Beautiful Concurrency
Resources
by Simon Peyton Jones
Haskell Simple Concurrency
by @eightyeight
Haskell Wiki
github.com/eightyeight/haskell-simple-concurrency
wiki.haskell.org
schoolofhaskell.com/school/advanced-haskell/beautiful-concurrency
Questions?
Intro to Concurrent Haskell
By Sean Hagstrom
Intro to Concurrent Haskell
A nice introduction to Concurrency in Haskell
- 301