7.2 Nebenläufigkeit von Tasks
391
schnittswert auf demselben Kanal übertragen. Die Task Fiiter liest N Werte aus
dem Kanal (und ignoriert diese) und liest dann den Durchschnittswert, multipliziert
diesen Wert mit c (c kann vom Port COEF gelesen werden) und schreibt das Ergebnis
auf den Port OUT. Der dritte Parameter der READ- und WRITE-Funktionsaufrufe ist die
Anzahl der zu lesenden oder zu schreibenden Werte. READ-Aufrufe sind blockierend,
WRITE-Aufrufe blockieren, wenn die Anzahl an Elementen im Kanal eine bestimmte
Obergrenze überschreitet. Die SELECT-Anweisung hat dieselbe Semantik wie die
gleichnamige Anweisung in Ada (siehe Seite 124): die Ausführung der Task wird
angehalten, bis eine Eingabe von einem der beiden Ports vorliegt. Dieses Beispiel
erfüllt alle Kriterien für die Aufteilung von Tasks, die im Rahmen von Abb. 7.9
aufgeführt wurden. Beide Tasks warten auf Eingaben, während sie bereits Ressourcen belegen. Die Effizienz könnte durch Umstrukturieren der beiden Tasks gesteigert
werden. Dabei reicht die einfache Aufteilung von Abb. 7.9 hier aber nicht aus. Bei der
von Cortadella et al. vorgeschlagenen Methode werden FlowC-Programme zunächst
in (erweiterte) Petrinetze übersetzt. Die Petrinetze für die einzelnen Tasks werden
dann zu einem einzigen Petrinetz zusammengefügt. Neue Tasks werden schließlich mit Hilfe von Ergebnissen aus der Petrinetz-Theorie erzeugt. Abb. 7.11 zeigt
eine mögliche neue Task-Struktur. In dieser gibt es eine Task, die alle InitialisieAbb. 7.11 Erzeugte Software-Tasks
rungen ausführt. Zudem gibt es je eine Task für jeden Eingabeport. Eine effiziente
Implementierung würde eine Unterbrechung für jede neue Eingabe an einem der
Ports erzeugen, wobei pro Port ein eindeutiger Interrupt verfügbar sein sollte. Die
Tasks könnten dann direkt durch die jeweiligen Interrupts gestartet werden, ohne
dass ein Aufruf des Betriebssystems erforderlich wäre. Kommunikation kann über
eine einzelne, gemeinsam benutzte globale Variable implementiert werden (wenn
Précédent

- 409/485

Suivant