Concurrency

0. Global State: IORef

1. Mutable State Via IORef

4. An API for Shared Message-Box-Variables MVar

An MVar can be used as

  1. A container for shared mutable state, e.g. common design pattern where threads need read and write some shared value: Represent the state as an ordinary immutable value in an MVar.

  2. A one-place message channel, which can be used for asynchronous communication between two threads.

  3. A lock : takeMVar acquires the lock and putMVar releases it again. An MVar used in this way can protect shared mutable state or critical sections.

  4. MVars: Bank Account/Deposit

Bank account revisited; using MVar depositing with different threads, and fuzzed scheduler

6. Asynchrony Via MVars

Lets implement asynchronous function calls (aka futures or promises) using MVars.

(Other languages “features” are Haskell’s functions …)

A type representing an Asynchronous Computation

Function to execute an IO action async-hronously

Function to wait for the result of Async computation

Application: Download a bunch of URLs asynchronously, without blocking on each other

To demo the below, build and run with:

A list of URLs

Reading a SINGLE URL

Exercise: What happens if you comment out the synchronize l ?

Btw, why are we using asyncMapM not something like forkMapM?

Try to use this instead of asyncMapM above and see if you can figure it out.

Hint: What happens after forking?

9. GLOBAL Locks means Zero Concurrency

Pretty silly if the entire bank froze up to handle a single customer!

AccountMV has a local lock per account, lets simulate with explicit lock.

Create a new “locked” account

Now, lets do concurrent deposits, but make sure we use the same lock…