Concurrent Haskell

Werbung
Concurrent Haskell
Bertram, Alexander & Wenzel, Sebastian
Fachhochschule Wedel - University of Applied Sciences
18. Dezember 2009
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied Sciences)
18. Dezember 2009
1 / 32
Gliederung
1
Nebenläufigkeit
2
Concurrent Haskell
3
Software Transactional Memory
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied Sciences)
18. Dezember 2009
2 / 32
Gliederung
1
Nebenläufigkeit
Grundlagen
Typische Probleme
2
Concurrent Haskell
Grundlagen
Threads
Synchronisation
Kommunikation
3
Software Transactional Memory
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied Sciences)
18. Dezember 2009
3 / 32
Grundlagen
Kurzdefinition: Nebenläufigkeit
Mehrere Ereignisse sind nebenläufig, wenn sie sich nicht gegenseitig
beeinflussen. Kein Ereignis darf Ursache eines anderen Ereignisses sein.
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied Sciences)
18. Dezember 2009
4 / 32
Grundlagen
Nebenläufigkeit in der Informatik
Aufteilung der Programmfunktionalität auf separate Prozesse oder
Threads
Synchronisation
Semaphoren
Locks
Monitore
Kommunikation
Message Passing
Mailboxen
Probleme
Deadlocks
Verhungern
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied Sciences)
18. Dezember 2009
5 / 32
Typische Probleme
Erzeuger-Verbraucher
Ein Erzeuger
Ein Verbraucher
Begrenzter Puffer
Problem, wenn mehr erzeugt / verbraucht als verbraucht / erzeugt
wird
Dinierende Philosophen
n Philosophen, die gelegentlich essen
2 Gabeln, links und rechts, zum Essen nötig
Problem: nur n Gabeln vorhanden
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied Sciences)
18. Dezember 2009
6 / 32
Typische Probleme
Leser-Schreiber
n Schreib-Prozesse
m Lese-Prozesse
Ein Datenbestand
Problem, wenn gleichzeitig geschrieben / gelesen wird
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied Sciences)
18. Dezember 2009
7 / 32
Gliederung
1
Nebenläufigkeit
Grundlagen
Typische Probleme
2
Concurrent Haskell
Grundlagen
Threads
Synchronisation
Kommunikation
3
Software Transactional Memory
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied Sciences)
18. Dezember 2009
8 / 32
Grundlagen
Erweiterung zu Haskell 98
Einführung des Nebenläufigkeit-Konzeptes in Haskell
Bibliothek Control.Concurrent muss importiert werden
Von GHC und Hugs unterstützt
In GHC und Hugs teilweise unterschiedlich implementiert
GHC bietet umfangreichere Unterstützung als Hugs
Concurrent.hs
...
# ifdef __G L AS G OW _ H AS K EL L _ _
...
# endif
...
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied Sciences)
18. Dezember 2009
9 / 32
Grundideen
Thread
Thread-Erzeugung
Möglichkeiten zur Prozesssynchronisation und -kommunikation
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
10 / 32
Threads
GHC vs. Hugs
GHC: Unterteilung in Haskell- und Betriebssystem-Threads
Hugs: Nur Haskell-Threads
Threads sind IO-Aktionen
Ausführung sofort nach Erzeugung
Thread zu Ende, wenn IO-Aktion zu Ende
Nicht-deterministisch
Thread-Zustand nach außen nicht sichtbar
ThreadId
Abstrakter Datentyp
GHC: Handle des erzeugten Thread
Hugs: Synonym für ()
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
11 / 32
Haskell-Threads
„Leichtgewichtig“
Overhead für die Erzeugung sehr klein
Overhead für den Kontextwechsel sehr klein
Scheduling intern in der Haskell-Laufzeitumgebung
Keine Betriebssystem-Bibliotheken nötig
Erzeugung
forkIO :: IO () -> IO ThreadId
Scheduling
GHC: Präemptiv
Hugs: Kooperativ
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
12 / 32
Haskell-Threads
forkIO-Beispiel
forkIO ( write ( take 10 ( repeat ’a ’) ) ) >>
write ( take 10 ( repeat ’b ’) )
where
write [] = putChar ’. ’
write ( c : cs ) = putChar c >> write cs
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
13 / 32
Haskell-Threads
GHC
* Main > main
bbbbbbbbbb . aaaaaaaaaa .
* Main > main
bb bababab ab ab aba ba . aa .
* Main > main
bb bababab ab ab aba ba . aa .
Hugs
Main > main
bbbbbbbbbb . aaaaaaaaaa .
Main > main
bbbbbbbbbb . aaaaaaaaaa .
Main > main
bbbbbbbbbb . aaaaaaaaaa .
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
14 / 32
Betriebssystem-Threads
Erzeugung
forkOS :: IO () -> IO ThreadId
Erstellung über Betriebssystem-Funktionen
Verwaltung vom Betriebssystem
Erstellen und Kontextwechsel teuer
Verwendung von Fremdbibliotheken möglich, in denen Threads mit
Thread-lokalen Speicher benötigt werden
Option -threaded beim Linken nötig
Option -threaded
$ ghc -c Main . hs
$ ghc - threaded -o Main Main . io
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
15 / 32
Blockierverhalten von Haskell-Threads
Problem
Haskell-Laufzeitumgebung verwendet nur einen Betriebssystem-Thread
Nur ein Haskell-Thread zur Zeit
Blockierende Operationen blockieren alle anderen Haskell-Threads
Ausnahme: I/O-Operationen in GHC
Lösung
Nur im GHC
Option -threaded beim Linken nötig
Verwendung der Multithread-Version der Haskell-Laufzeitumgebung
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
16 / 32
Gebundene Threads
Bindung eines Haskell-Threads an einen Betriebssystem-Thread
Verwaltung des Haskell-Threads von der Haskell-Laufzeitumgebung
Verwendund des Betriebssystem-Thread für die Kommunikation mit
Fremdbibliotheken
Main-Thread ist immer ein gebundener Thread
Option -threaded beim Linken nötig
Erzeugung
forkOS :: IO () -> IO ThreadId
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
17 / 32
Concurrent.hs
Zusätzliche Funktionen
myThreadId :: IO ThreadId
killThread :: ThreadId -> IO ()
yield :: IO ()
threadDelay :: Int -> IO ()
r t s S u pp o r t s B o u n d T h r e a d s :: Bool
isC urrent T h r ea d B o u n d :: IO Bool
runInBoundThread :: IO a -> IO a
ru nInUnbo un dT hre ad :: IO a -> IO a
Die meisten der genannten Funktionen sind nur im GHC verfügbar.
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
18 / 32
Synchronisation
Möglich durch sogenannte „Mutable Variable“
Entweder leer oder voll
Definition
data MVar a
Operationen
takeMVar :: MVar a -> IO a
putMVar :: MVar a -> a -> IO ()
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
19 / 32
Synchronisation
„Sterbende“ Philosophen
philosoph :: Int -> MVar () -> MVar () -> IO ()
philosoph n left right = do
takeMVar left
takeMVar right
-- eat
putMVar left ()
putMVar right ()
philosoph n left right
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
20 / 32
Synchronisation
Dinierende Philosophen
philosoph :: Int -> MVar () -> MVar () -> IO
philosoph n left right = do
takeMVar left
empty <- isEmptyMVar right
if empty then
putMVar left ()
philosoph n left right
else do
takeMVar right
-- eat
putMVar left ()
putMVar right ()
philosoph n left right
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
21 / 32
Kommunikation
Auch über MVars
Einelementiger Puffer
Operationen
newEmptyMVar :: IO (MVar a)
newMVar :: a -> IO (MVar a)
takeMVar :: MVar a -> IO a
putMVar :: MVar a -> a -> IO ()
Im GHC auch über Exceptions möglich
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
22 / 32
Kommunikation - Beispiel
Erzeuger
producer :: MVar Int -> IO ()
producer mVar = do
putStrLn $ " Sende einen Wert "
putMVar mVar 42
putStrLn $ " Gesendet : 42 "
Verbraucher
consumer :: MVar Int -> IO ()
consumer mMar = do
putStrLn $ " Warte auf einen Wert "
x <- takeMVar mVar
putStrLn $ " Empfangen : " ++ ( show x )
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
23 / 32
Kommunikation - Beispiel
Aufruf
sta rtProd u c e r C o n s u m e r = do
mVar <- newEmptyMVar
forkIO ( producer mVar )
consumer mVar
Ausgabe
* Main > st a r t P r o d u c e r C o n s u m e r
Verbraucher : Warte auf einen Wert
Erzeuger : Sende 42
Erzeuger : 42 gesendet
Verbraucher : 42 empfangen
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
24 / 32
MVar.hs
Zusätzliche Funktionen
readMVar :: MVar a -> IO a
swapMVar :: MVar a -> a -> IO a
tryTakeMVar :: MVar a -> IO ( Maybe a )
tryPutMVar :: MVar a -> a -> IO Bool
isEmptyMVar :: MVar a -> IO Bool
withMVar :: MVar a -> ( a -> IO b ) -> IO b
modifyMVar_ :: MVar a -> ( a -> IO a ) -> IO ()
modifyMVar :: MVar a -> ( a -> IO (a , b ) ) -> IO b
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
25 / 32
Kommunikation über Channels
Definition
data Chan a =
Chan ( MVar ( Stream a ) ) -- read end
( MVar ( Stream a ) ) -- write end
type Stream a = MVar ( ChItem a )
data ChItem a = ChItem a ( Stream a )
Abstrakter Datentyp
Repräsentiert unbegrenzten FIFO Puffer
Ermöglicht synchrones Schreiben und Lesen
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
26 / 32
Chan.hs
Operationen
newChan :: IO ( Chan a )
writeChan :: Chan a -> a -> IO ()
readChan :: Chan a -> IO a
dupChan :: Chan a -> IO ( Chan a )
unGetChan :: Chan a -> a -> IO ()
isEmptyChan :: Chan a -> IO Bool
getChanContents :: Chan a -> IO [ a ]
writeList2Chan :: Chan a -> [ a ] -> IO ()
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
27 / 32
Gliederung
1
Nebenläufigkeit
Grundlagen
Typische Probleme
2
Concurrent Haskell
Grundlagen
Threads
Synchronisation
Kommunikation
3
Software Transactional Memory
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
28 / 32
Probleme mit nebenläufigen Programmen
Synchronisation und Kommunikation
Zu wenige Locks
Zu viele Locks
Falsche Locks
Reihenfolge der Locks
Lösung: Transaktion
Atomarität
Kontinuität
Isolation
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
29 / 32
Software Transactional Memory
STM-Monade
Kann mit atomically mehrere STM-Aktionen sequentiell ausführen
atomically :: STM a -> IO a
Arbeitet mit TVars
data TVar a
newTVar :: a -> STM ( TVar a )
readTVar :: TVar a -> STM a
writeTVar :: TVar a -> a -> STM ()
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
30 / 32
Beispiel
Bank-Konten
type Account = TVar Int
transfer :: Account -> Account -> Int -> IO ()
transfer from to amount = atomically ( do {
deposit to amount ;
withdraw from amount })
withdraw :: Account -> Int -> STM ()
withdraw account amount = do
balance <- readTVar account
writeTVar account ( balance - amount )
deposit :: Account -> Int -> STM ()
deposit acccount amount =
withdraw account ( - amount )
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
31 / 32
Ende
Vielen Dank für die Aufmerksamkeit!
Schöne Feiertage!
Frohes Fest!
Und einen Guten Rutsch!
Bertram, Alexander & Wenzel, Sebastian (Fachhochschule
Concurrent
Wedel
Haskell
- University of Applied 18.
Sciences)
Dezember 2009
32 / 32
Herunterladen