Explicit Concurrent Programming in Haskell

Download Explicit Concurrent Programming in Haskell

Post on 01-Feb-2016

30 views

Category:

Documents

0 download

Embed Size (px)

DESCRIPTION

Explicit Concurrent Programming in Haskell. QIAN XI COS597C 10/28/2010. Outline. Recap of IO Monad Thread Primitives Synchronization with Locks Message Passing Channels Software Transactional Memory Transactional Memory with Data Invariants. IO Monad in Haskell. Why Monad? - PowerPoint PPT Presentation

TRANSCRIPT

<ul><li><p>QIAN XICOS597C 10/28/2010Explicit Concurrent Programming in Haskell </p></li><li><p>OutlineRecap of IO MonadThread PrimitivesSynchronization with Locks Message Passing Channels Software Transactional MemoryTransactional Memory with Data Invariants</p></li><li><p>IO Monad in HaskellWhy Monad?Pure functional language needs determinism. </p><p>What is Monad?an abstract data type: IO a, e.g. IO Inta container of impure, suspended actions/computations How to use Monad?</p><p>= 7= 7?do encloses a sequence of computations:an action,a pattern bounded to the result of an action using </p></li><li><p>Creating Haskell ThreadsforkIO :: IO () -&gt; IO ThreadId</p><p>forkOS :: IO () -&gt; IO ThreadIdsupport certain kinds of foreign calls to external code.</p><p>Concurrency is lightweight: both thread creation and context switching overheads are extremely low. The parent thread will not automatically wait for the child threads to terminate.</p><p>Ex: fibEuler.hs</p></li><li><p>Mutable VariableHaskell threads communicate through Mvars (mutable variables).MVar writes and reads occur atomicallyA MVar may be empty or it may contain a valuewrite to occupied MVar, read from empty MVar: will be blockedwill be rewoken when its empty/ a value is written and try againwake up scheme: FIFO</p></li><li><p>MVar Operationsdata MVar anewEmptyMVar :: IO (MVar a)newMVar :: a &gt; IO (MVar a) takeMVar :: MVar a &gt; IO a putMVar :: MVar a &gt; a &gt; IO ()readMVar :: MVar a &gt; IO atryTakeMVar :: MVar a &gt; IO (Maybe a)tryPutMVar :: MVar a &gt; a &gt; IO BoolisEmptyMVar :: MVar a &gt; IO Bool</p></li><li><p>Example: Make A Rendezvous</p></li><li><p>Message Passing Channelsunbounded FIFO channeldata Chan anewChan :: IO (Chan a)writeChan :: Chan a -&gt; a -&gt; IO ()readChan :: Chan a -&gt; IO aunGetChan :: Chan a -&gt; a -&gt; IO ()isEmptyChan :: Chan a -&gt; IO BooldupChan :: Chan a -&gt; IO (Chan a)...Ex: chat.hs</p></li><li><p>Haskell STMProgramming with MVar can lead to deadlockone thread is waiting for a value to appear in an MVarno other thread will ever write a value to that MVar An alternative way to synchronize: software transactional memory (STM)A special type of shared variable: TVarTVars are used only inside atomic blocks.The code inside an atomic block is executed as if it were an atomic instruction.Functionally, no other thread is running in parallel/interleaved.In reality, a log is used to roll back execution if conflicts.</p></li><li><p>TVar Operationsdata STM a A monad supporting atomic memory transactions atomically :: STM a &gt; IO a Perform a series of STM actions atomically </p><p>data TVar a Shared memory locations that support atomic memory operations newTVar :: a &gt; STM (TVar a) Create a new TVar with an initial value readTVar :: TVar a &gt; STM a Return the current value stored in a TVar writeTVar :: TVar a &gt; a &gt; STM () Write the supplied value into a TVar</p></li><li>7bal :: TVar IntThread 11 atomically (do2 v </li><li>bal :: TVar Int8Thread 11 atomically (do2 v </li><li><p>When To Use retry and orElse?retry :: STM a abort the current transaction re-execute it from the beginning using a fresh log</p><p>orElse :: STM a -&gt; STM a -&gt; STM acompose two transactionsif one transaction aborts then the other transaction is executedif it also aborts then the whole transaction is re-executed</p><p>Ex: account.hs</p></li><li><p>Case Study: ArrayBlockingQueue (Discolo et al. FLOPS 06)from JSR-166, a java implementation of a fixed length queueselect 3 representative interfaces:take: Removes an element from the head of the queue, blocking if the queue is emptypeek: Removes an element from the head of the queue if one is immediately available, otherwise return NothingpullTimeout: Retrives and removes the head of this queue, waiting up to the specified wait time if necessary for an element to become available</p></li><li><p>Data Structure</p></li><li><p>function: take</p></li><li><p>function: peek</p></li><li><p>helper function: readHeadElement</p></li><li><p>A More Complex Function: pollTimeoutlock-based mechanism has no support for composing two concurrency abstractions</p></li><li><p>Performance Measurements(Discolo et al. FLOPS 06)The testcreates an ArrayBlockingQueue of type integercreates an equal number of reader and writer threads that simply loops for the specific number of iterations performing taking or put operations on the queuecompletes when all threads have terminatedFor each processor configuration (1-8 processors)varies only the number of reader/writer threads</p></li><li><p>STM with Data InvariantsSTM can also deal with consistency of the programcheck E where E is an invariant that should be preserved by every atomic updatecheck :: Bool -&gt; STM a check True = return () check False = retry account.hs with invariants</p></li><li><p>ReferencesA Tutorial on Parallel and Concurrent Programming in Haskell, Jones et al., AFP summer school notes, 2008Lock Free Data Structures using STM in Haskell, Discolo et al., FLOPS 2006http://haskell.org/haskellwiki/Haskell_for_multicores...</p><p>**************</p></li></ul>