Concurrent Haskell extendsHaskell 98 with explicit concurrency. The two main concepts underpinning Concurrent Haskell are:
Built atop this is a collection of useful concurrency and synchronisation abstractions such as unbounded channels, semaphores and sample variables.
Default Haskell threads have very low overheads: creation, context-switching and scheduling are all internal to the Haskell runtime. These Haskell-level threads are mapped onto a configurable number of OS-level threads, usually one per processor core.
The Software Transactional Memory (STM) extension to the Glasgow Haskell Compiler reuses the process forking primitives of Concurrent Haskell. STM however:
The STM monad is an implementation of Software Transactional Memory in Haskell. It is implemented in the GHC compiler, and allows for mutable variables to be modified in transactions. An example of a transaction might be in a banking application. One function that would be needed would be a transfer function, which takes money from one account, and puts it into another account. In the IO monad, this might look like this:
This might work some of the time, but causes problems in concurrent situations where multiple transfers might be taking place on the same account at the same time. If there were two transfers transferring money from account 'from', and both calls to transfer ran the
line before either of them had written their new values, it is possible that money would be put into the other two accounts, with only one of the amounts being transferred being removed from account 'from', thus creating a race condition. This would leave the banking application in an inconsistent state.
A traditional solution to such a problem is locking. For instance, one could place locks around modifications to an account to ensure that credits and debits occur atomically. In Haskell, locking is accomplished with MVars:
Using such procedures will ensure that money will never be lost or gained due to improper interleaving of reads and writes to any individual account. However, if one tries to compose them together to create a procedure like transfer: