10. Parallele Prozesse
 
zurück
  10.7 Fortgeschrittener Umgang mit Prozessen
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;



 
zurück
 Index   Ada Tour - Dokumentation  
© 2003 Förderverein Ada Deutschland e.V.