3 Datenfluss

Werbung
Klaus-Peter Löhr!
3 Datenfluss!
3.1 Spezifikation von Filtern !
3.2 Implementierung von Filtern
3.3 Komposition über Kanäle!
Zusammenfassung
!
!
WS 13/14
ALP 5 - Datenfluss
!2!
!4!
!10!
!31!
1
3.1 Spezifikation von Filtern!
Spezifikation eines Filters Filter:
Abbbildung von Eingabefolgen auf Ausgabefolgen
Œ Signatur: getypte Ein/Ausgabe-Ports, z.B.
filter :: Param->[X]->[Y] -> ([U], [V])
 Semantik:
filter p x y = .....!
WS 13/14
ALP 5 - Datenfluss
2
Termination von Filtern: bei endlichen Eingabefolgen
mit Ende-Markierungen wie [], ^D, "EOF", ‘.', ...!
terminierend: Spezifikation fordert endliche E/A-Folgen
Beispiele:
Unix sort, Haskell sort, sum
u.U. terminierend: E/A-Folgen können unendlich sein
Beispiele:
Unix grep, Haskell filter!
!
nichtterminierend: Eingabefolgen müssen unendlich sein
(d.h. Filter wartet grundsätzlich auf Eingabe)
WS 13/14
ALP 5 - Datenfluss
3
3.2 Implementierung von Filtern!
Voraussetzung: die Programmiersprache verfügt über
kanalbezogene Kommunikationsmechanismen (2.3, S.20)!
Es folgen Beispiele für diesen Spezialfall:
in1!
in2!
out1!
filter
out2!
(filter der Einfachheit halber ohne weitere Parameter)
!
WS 13/14
ALP 5 - Datenfluss
4
Œ Occam:
(inspiriert von CSP [Hoare 1985])
!
!PROC filter(CHAN OF INT in1, in2, out1, out2) !
! SEQ .....!
!
in1 ? mesvar !
!
!Empfangen !
!
.....!
!
out2 ! message
!
!Senden !
!
ALT
!
!
!
!disjunktives Empfangen !
!
in1 ? mesvar!
!
out1 ! message!
!
guard & in2 ? mesvar
!verzögertes Empfangen !
!
out2 ! message!
!:!
l synchrone Kommunikation (ungepuffert!)
l höchstens je ein Sender und Empfänger je Kanal!
WS 13/14
ALP 5 - Datenfluss
5
!
 Go:
!
!func
!
!
!
!
!
!
!
!
!
!
!}!
[Google 2007]
filter(in1, in2 <-chan int, !
out1, out2 chan<- int) {!
mesvar := <-in1
!
!Empfangen !
.....!
out2 <- message
!
!Senden !
select {
!
!
!disjunktives(!) Empfangen !
case mesvar := <-in1 :!
...!
case mesvar := <-in2 : ! !
...!
}!
l synchrone oder asynchrone Kommunikation
WS 13/14
ALP 5 - Datenfluss
6
Ž Unix (hier mit C):
// usage: filter in2 out2
!int main(int argc, char** argv) {!
!read(0, &message, count); ...
!Empfangen !
!int c = open(argv[2], flags);
!(aktualisiere out2)!
!write(c, message, count); ...!
!Senden !!
!} !
l beschränkt gepuffert
l Erstes Argument von read/write („file descriptor“) ist
Portnummer : 0/1/2 = Standard-E/A/Fehler-Kanäle.
Zusätzlich: 3/4/... „durch explizite Aktualisierung“
gemäß Kanalnamen im Argumentvektor.
l disjunktives Empfangen/Senden mit select-Systemaufruf
l keine Typisierung: Bytestrom!
WS 13/14
ALP 5 - Datenfluss
7
 Haskell:
filter :: [Int]->[Int] -> ([Int],[Int])
filter x y = (u,v) where !
!
!
u = ...!
!
!
v = ...!
l synchrone Kommunikation (ungepuffert),
vermittelt durch verzögerte Listen (lazy lists, streams) !
l Argumente = Eingabefolgen
anonymes Ergebnis = Tupel der Ausgabefolgen
„Ports“ x y u v
l „Senden“ = Listenkopf zur Verfügung stellen
„Empfangen“ = Listenkopf übernehmen
l starke Typisierung
WS 13/14
ALP 5 - Datenfluss
8
Haskell: Einfache Anbindung an Standard-Ein/Ausgabe !
interact :: (String -> String) -> IO ()!
!
macht interact f zum Filter mit Standard-E/A !
Beispiel: Programmdatei lower.hs enthält Haskell-Skript
!
!
!
!
!import Data.Char!
!main = interact (map toLower)!
è
!
WS 13/14
!runhugs lower !
!wandelt für die Ausgabe alle eingelesenen
Buchstaben in Kleinbuchstaben um
ALP 5 - Datenfluss
9
3.3 Komposition über Kanäle!
x!
a!
y!
b!
(2)
(1)
u!
c!
d!
w!
v!
(3)
WS 13/14
ALP 5 - Datenfluss
10
(1) Rückkoppelung (Zyklus): möglich, in der Praxis selten
(typisch: Datenflussmaschine [2.3, S. 17])
(2) Verschmelzen: nichtdeterministisch, oft akzeptabel
(typisch: gleichartige Daten aus mehreren Quellen)
(3) Splitten: nichtdeterministisch, selten akzeptabel
(typisch: Lastverteilung)
Beachte:
WS 13/14
Wenn alle Filter determiniert sind und jeder Kanal
höchstens je einen Sender und Empfänger hat,
ist das zusammengesetzte Programm determiniert.
Es ist selbst wiederum als Filter einsetzbar.
ALP 5 - Datenfluss
11
Verklemmungsgefahr: steigt mit sinkender Pufferkapazität
Verklemmungsfreiheit liegt genau dann vor, wenn
Ø  unbeschränkte Pufferung:
Zyklenfreiheit
Ø  beschränkte Pufferung:
Kreisfreiheit*
Ø  keine Pufferung:
Kreisfreiheit*
* d.h. bei Ignorierung der Kantenrichtungen
WS 13/14
ALP 5 - Datenfluss
12
Fairness:
betrifft die Behandlung blockierender
Kommunikationsoperationen beim
Verschmelzen oder Splitten
Ø  unbeschränkte Pufferung:
nur Empfangen kann blockieren
Ø  beschränkte Pufferung:
auch Senden kann blockieren
Ø  keine Pufferung:
auch Senden kann blockieren
E In jedem Fall ist FCFS wünschenswert.
WS 13/14
ALP 5 - Datenfluss
13
Beschreibung der Komposition:
Œ graphisch (wie auf S. 9)
 mit eigener Koordinations/Kompositionssprache
Ž mit Implementierungssprache der Komponenten
! In jedem Fall formale Sprache mit Syntax und Semantik !
WS 13/14
ALP 5 - Datenfluss
14
3.3.1 ... mit graphischer Komposition!
! Viele Ansätze in der Forschung - wenig praktische Systeme !
Beispiel 1: LabVIEW
Graphische „Datenflusssprache“ für Laborautomatisierung aber eher graphische Beschreibung
von Datenabhängigkeiten als
Komposition nichtsequentieller
Programme.
Automatische Codeerzeugung.
WS 13/14
ALP 5 - Datenfluss
15
(Quelle: http://www.upscale.utoronto.ca/PVB/LabView.html )
WS 13/14
ALP 5 - Datenfluss
16
Beispiel 2: Flow - ähnlich LabVIEW
WS 13/14
ALP 5 - Datenfluss
17
(Quelle: http://www.mi.fu-berlin.de/inf/groups/ag-tech/projects/flow/ )
WS 13/14
ALP 5 - Datenfluss
18
3.3.2 ... mit Koordinationssprache!
Populär sind Skriptsprachen, die von den Mechanismen des
Betriebssystems zur Interprozesskommunikation Gebrauch machen.
Beispiel Unix:
Ø  schwergewichtige Prozesse
Ø  Pipes und Named Pipes als Kanäle
Ø  Konfigurierung statisch (deklarativ) und/oder dynamisch (imperativ)
Ø  beschränkt gepuffert, nach FCFS bedient
Ø  Senden/Empfangen blockiert, bis Empfänger/Sender vorhanden.
Ø  Sendeversuch verursacht Ausnahme SIGPIPE (Fehler „Broken Pipe“),
wenn kein Empfänger mehr vorhanden.
Ø  Empfangen liefert den Wert 0, wenn kein Sender mehr vorhanden.
WS 13/14
ALP 5 - Datenfluss
19
Statisches Konfigurieren mit der Unix Shell:
Verteiltes Programm rein deklarativ mittels Operator & :
!
!x & y & z & x & ...!
Pipe-Operator | an Stelle von & :
vereinbart anonymen Kanal (= Pipe) zwischen den
beiden Operanden, der die Ports 1 bzw. 0 im
linken bzw. rechten Operanden aktualisiert
!
Named Pipes („fifos“)
ermöglichen beliebige Datenfluss-Graphen:
WS 13/14
ALP 5 - Datenfluss
20
Named Pipes
ermöglichen beliebige Datenfluss-Graphen:
1. Weitere Kanäle imperativ als Named Pipes bereitstellen:
!
!z.B.
mkfifo a b c d ...!
2. Die Filter mit diesen Kanälen passend parametrisieren, z.B.
!
WS 13/14
x a b
&
y b c
& ...!
Achtung:
ob ein Argument als Ein- oder Ausgabekanal
oder als „normaler“ Parameter fungiert,
ist der Spezifikation von x zu entnehmen!
3. Die Named Pipes wieder abräumen:
rm a b c ...
ALP 5 - Datenfluss
21
Zur Erinnerung:
Ein/Ausgabe-Umlenkung mit < bzw. > wie z.B. in!
!
!
!
!cat <a >b!
!
wobei a,b Dateien - aber auch Named Pipes sein können !
Beispiel: statt
x a b
Standard-E/A einbeziehen:
x a >b
( ist äquivalent mit
x a
mit leicht geänderten x und y !
WS 13/14
ALP 5 - Datenfluss
&
y b c
!
&
|
y <b c
!
y c
)
22
Prinzip: System aus Filtern ist selbst wieder Filter !
Ø  Skript mit formalen Parametern $1,$2,.., z.B. für 2.3, S. 18:
!
!mkfifo x
!
!merge $1 $2 >x & merge x $3 !
!rm x
!
Ø  Benennung durch Dateinamen des Skripts, z.B. merge3.sh
!(keine Vereinbarung von formalen Parametern)
Ø  Als Programm deklarieren durch Erteilung des x-Rechts
Ø  Ausführung mit aktuellen Parametern wie normales Programm,
z.B.
merge3.sh in1 in2 in3 WS 13/14
ALP 5 - Datenfluss
23
Beispiel für „System als Subsystem verwenden“:
Programm check.sh enthält
!
!runhugs lower <$1 | java Check $2 !
Damit Programm checkgerman.sh !
!
!
!
!check.sh $1 german.dic | sort | uniq -u!
angewendet z.B. so:
!
checkgerman.sh mytext!
Weitere Möglichkeiten der Shell, z.B.
!
WS 13/14
!a|b|c
&
x|y|z
&
ALP 5 - Datenfluss
! (è man bash)
24
Die beteiligten Filter können in beliebigen Sprachen
implementiert sein (deren E/A auf der Unix-E/A basiert) !
Ein Skript kann selbst wiederum als Filter fungieren !
WS 13/14
ALP 5 - Datenfluss
25
Das Beispiel von S. 9:
#!/bin/bash
# usage: page9 <in2 in1 out1 >out2!
mkfifo a b c d!
!x a b
<$1
\ !
& !y <a b >d
\!
& !u
c d
\!
& !v
<c
\!
& !w
c d
>$2 !
rm a b c d!
!
!
Übungsfrage: welche Annahmen über die StandardE/A-Ports der beteiligten Programme werden hier gemacht?
WS 13/14
ALP 5 - Datenfluss
26
3.3.3 ... mit textueller Programmiersprache!
... in der auch die Komponenten geschrieben sind, z.B.
Occam, Go, Haskell, ..., Datenflußsprachen [Johnston et al. 2004]
Occam (S. 5): Beispiel Verschmelzung wie in 2.3, S. 18:
PROC merge3(CHAN OF INT in1, in2, in3, out)!
! CHAN OF INT x :!
! PAR!
!
merge(in1,in2,x)!
!
merge(in3,x,out)!
!:!
WS 13/14
ALP 5 - Datenfluss
27
Go (S. 6):
func merge3(in1, in2, in3 <-chan int,!
!
out chan<- int) {!
!
x := make(chan int, 100)!
!
go merge(in1, in2, x)!
!
go merge(x, in3, out)!
!}!
!
!
Beachte:
WS 13/14
go hat die Funktionsweise eines fork.
Der Aufruf von merge3 bewirkt eine
„imperative, schrittweise Erzeugung“ der
Komponenten des Datenflusssystems
(dagegen deklarativ bei Occam)
ALP 5 - Datenfluss
28
Haskell (S. 8): „stream processing“
merge3 :: Num a => [a]->[a]->[a] -> [a]!
!merge3 in1 in2 in3 =!
!
merge (merge in1 in2) in3!
in1!
in2!
in3!
merge
(x)!
merge
(out)!
Keine echte Nichtsequentialität in Haskell!
(Aber: Communicationg Haskell Processes [CHP])
WS 13/14
ALP 5 - Datenfluss
29
Beispiel Partialsummen von Skalarprodukt wie in 2.3, S. 17:
sumprod x y = b where!
a = zipWith(*) x y!
b = zipWith(+) a (0:b)
0
x!
*
y!
a!
+
b!
Generell: Zyklus im Graphen entspricht Rekursion im Text
Haskell-Literatur ist reiche Quelle komplexer Beispiele
WS 13/14
ALP 5 - Datenfluss
30
Zusammenfassung!
Ø  Spezifikation der Filter
Ø  Implementierung der Filter mit Programmiersprache
Ø  Komposition der Filter über Kanäle
- mit graphischer Sprache
- mit Koordinations/Kompositionssprache
- mit Programmiersprache
Ø  determiniert, wenn kein Splitten/Verschmelzen
Ø  aber Verklemmungsgefahr
Ø  komponiertes System ist wiederum Filter!
WS 13/14
ALP 5 - Datenfluss
31
Quellen!
C.A.R Hoare:
Communicating Sequential Processes. Prentice-Hall 1985.
http://www.usingcsp.com/
INMOS:
Occam 2.1 Reference Manual. INMOS 1995.
http://www.wotug.org/occam/documentation/oc21refman.pdf
Google:
Go. http://golang.org/
J.P. Morrison: Flow-Based Programming. Morrison Enterprises 2010 (2. ed.).
ISBN 0-442-1771-5
W.M. Johnston et al.: Advances in Dataflow Programming Languages.
ACM Computing Surveys 36.1, March 2004
(Fortsetzung:)
WS 13/14
ALP 5 - Datenfluss
32
Quellen (Fortsetzung)
Unix/Linux...:
pubs.opengroup.org/onlinepubs/9699919799/
www.FreeBSD.org/
www.linuxmanpages.com/
dell9.ma.utexas.edu/cgi-bin/man-cgi?pipe+7
Haskell:
www.haskell.org/haskellwiki/Haskell
en.wikibooks.org/wiki/Haskell
www.haskell.org/haskellwiki/Concurrency
www.cs.kent.ac.uk/projects/ofa/chp/
CHP:
LabVIEW:
www.ni.com/gettingstarted/labviewbasics/d/
Flow:
www.mi.fu-berlin.de/inf/groups/ag-tech/projects/flow/
WS 13/14
ALP 5 - Datenfluss
33
Herunterladen