|
10.7.1 Familien mit Prozesseingängen
Dieser Abschnitt stellt Erweiterungen des Rendezvouskonzeptes vor und
zeigt auf, wie Prozesse beeinflußt werden können.
Prozeßeingänge lassen sich mit einem diskreten Typ als Index
vereinbaren und ansprechen. Das Ergebnis ist eine Familie von Eingängen.
Solche Familien von Prozeßeingängen werden immer dann genutzt,
wenn sich hinter den verschiedenen Eingängen z. B. immer der gleiche
Algorithmus mit geringen Abweichungen verbirgt.
Beispiel:
Eine Funktion "berechnung" ist ein Näherungsalgorithmus,
der abhängig von einer Schranke das korrekte Ergebnis unterschiedlich
genau annähert. In einem solchen Fall ließe sich eine Familie
mit drei Eingängen konstruieren.
-- Spezifikation
package familie is
-- Bei 'gering' wird eine Ueberschlagsrechnung durchgefuehrt,
die sehr
-- schnell ablaeuft.
-- Bei 'normal' werden empirische Vorgaben als Abbruchkriterium
-- angesetzt, die ein genaues Ergebnis erwarten
lassen.
-- Bei 'doppelt' wird solange gerechnet, bis weitere
Iterationen kein
-- besseres Ergebnis liefern.
type genauigkeit is ( einfach, normal, doppelt );
-- Prozessdefinition
task type iteration is
entry input( genauigkeit ) ( x
: in integer ); -- Eine Familie mit drei Eingaengen.
entry output( x : out float );
end iteration;
end familie;
-- Rumpf
with text_io;
package body familie is
task body iteration is
f : float := 0.0;
i : integer := -1;
t : genauigkeit;
begin
select
accept input(
einfach ) ( x : in integer ) do
-- Notieren,
dass dieser Eingang aufgerufen wurde.
t
:= einfach;
i
:= x;
end input;
or
accept input(
normal ) ( x : in integer ) do
-- Notieren,
dass dieser Eingang aufgerufen wurde.
t
:= normal;
i
:= x;
end input;
or
accept input(
doppelt ) ( x : in integer ) do
-- Notieren,
dass dieser Eingang aufgerufen wurde.
t
:= doppelt;
i
:= x;
end input;
end select;
--Iteration, in Abhaengigkeit
vom aufgerufenen Eingang.
f := float( i );
accept output( x : out float ) do
x := f;
end output;
end iteration;
end familie; |
Eine weitere Möglichkeit, Eingangsfamilien zu nutzen, bietet sich an,
wenn der diskrete Typ eine Priorität darstellt. Dann ist die Select-Anweisung
so aufgebaut, daß zuerst der Eingang mit der höchsten Priorität
abgefragt wird und danach alle weiteren Eingänge ihrer Priorität
nach. Allerdings ist das nur praktikabel, wenn die Anzahl der verschiedenen
Prioritäten gering ist.
Beispiel:
package Prio_Server is
type PRIORITAET is (NIEDRIG, MITTEL, HOCH);
task type SERVER_TASK is
entry Anfrage (PRIORITAET) (X
: in INTEGER );
end SERVER_TASK;
end Prio_Server;
package body Prio_Server is
task body SERVER_TASK is
Lokal_X : INTEGER;
begin -- SERVER_TASK
loop
-- Eingänge
in absteigender Priorität durchlaufen
for Prio in
reverse PRIORITAET loop
select
accept
Anfrage (Prio) (X : in INTEGER) do
Lokal_X
:= X;
end
Anfrage;
--... Verarbeitung von Lokal_X
exit;
-- Prio-Schleife verlassen
else
-- kein Rendezvous -> naechste Priorität
null;
-- busy waiting!!
end
select;
end loop; --
Prio
end loop;
end SERVER_TASK;
end Prio_Server; |
|