Haskell/Concurrency
From Wikibooks, the open-content textbooks collection
[edit] Concurrency
Concurrency in Haskell is mostly done with Haskell threads. Haskell threads are user-space threads that are implemented in the runtime. Haskell threads are much more efficient in terms of both time and space than Operating System threads. Apart from traditional synchronization primitives like semaphores, Haskell offers Software Transactional Memory which greatly simplifies concurrent access to shared memory.
The modules for concurrency are Control.Concurrent.* and Control.Monad.STM.
[edit] Example
Example: Downloading files in parallel
downloadFile :: URL -> IO () downloadFile = undefined downloadFiles :: [URL] -> IO () downloadFiles = mapM_ (forkIO . downloadFile)
[edit] Software Transactional Memory
Software Transactional Memory (STM) is a mechanism that allows transactions on memory similar to database transactions. It greatly simplifies access to shared resources when programming in a multithreaded environment. By using STM, you no longer have to rely on locking.
To use STM, you have to include Control.Monad.STM. To change into the STM-Monad the atomically function is used. STM offers different primitives (TVar, TMVar, TChan and TArray) that can be used for communication.
The following example shows how to use a TChan to communicate between two threads. The channel is created in the main function and handed over to the reader/writerThread functions. The readerThread waits on the TChan for new input and prints it. The writerThread writes some Int-values to the channel and terminates.
Example: Communication with a TChan
import Control.Monad.STM
import Control.Concurrent
import Control.Concurrent.STM.TChan
oneSecond = 1000000
writerThread :: TChan Int -> IO ()
writerThread chan = do
atomically $ writeTChan chan 1
threadDelay oneSecond
atomically $ writeTChan chan 2
threadDelay oneSecond
atomically $ writeTChan chan 3
threadDelay oneSecond
readerThread :: TChan Int -> IO ()
readerThread chan = do
newInt <- atomically $ readTChan chan
putStrLn $ "read new value: " ++ show newInt
readerThread chan
main = do
chan <- atomically $ newTChan
forkIO $ readerThread chan
forkIO $ writerThread chan
threadDelay $ 5 * oneSecond