Programowanie współbieżne i rozproszone - Ada EAIiE Katedra Automatyki 2011
Hello Ada with Ada.Text_Io;use Ada.Text_Io; procedure Main is type MyInt is range 1..6; begin Put_Line("witaj Ada"); for I in 1..20 loop Put(".");Put(Integer Image( I )); delay(0.2); end loop; end Main;
Typy danych type Identyfikator is...; type Kolor is (Czerwony,Zielony,Niebieski); C:Kolor; D:Kolor:= Zielony; E:constant Kolor:=Niebieski; Żadnego Żadnego kombinowania, kombinowania, że że "Czerwony" "Czerwony" to to "1" "1" a a "Niebieski" "Niebieski" to to "3"! "3"!
Podtypy subtype Identyfikator is Typ...; subtype Dzien is Integer range 1..31; subtype P_Tydzien is Dzien range 1..7; subtype Dodatni is Integer range 1..Integer Last ; Dodatni First = 1; Dodatni Last = Integer Last;
Konwersja typów X: Integer:=2; Y: Float:=3.14; Z: Float; X+Y NIE Z := Float(X) + Y TAK Float(I) konwersja Integer (I) kwalifikacja
Tablice A:array(Integer range 1..10) of Float; AA:array (Integer range 1..10, Integer range 1..3) of Float ; PrzedTelewizorem : array (Dzien) of Float; A:array (Integer range 1..3) of Float := (0.0,0.0,0.0); A:array ( Integer range 1..3, 1..2) of Float := ((0.0,0.0), (0.0,0.0), (0.0,0.0)); A:array (Integer range 1..3, Dzien, Kolor) of Float range 0.456..3.14 ;
Typy danych X: array (1..10) of Float; Y: array (1..10) of Float; Y:= X ; NIE X,Y: array(1..1 0) of Float; Y:=X; NIE
Instrukcje sterujące for i in 1..Ile loop <instrukcje> end loop; while <warunek> loop <instrukcje> end loop; for i in reverse 1..Ile loop <instrukcje> end loop; Etykieta: loop <instrukcje> end loop;
Instrukcje sterujące if <warunek> then exit end if; exit when <warunek>; exit Etykieta when <warunek>;
Instrukcje sterujące if <warunek 1> then <instrukcje> elsif <warunek 2> then... <instrukcje> else <instrukcje> end if; case <wyrazenie> is when <wartosc 1> => <instrukcje 1> when <wartosc 2> => <instrukcje 2> when <w1> <w2> => <instrukcje 3>... when others => <instrukcje n> end case;
Blok instrukcji, goto declare -- deklaracje zmiennych begin -- instrukcje end <<bardzo_bardzo_niedobrze>> goto bardzo_bardzo_niedobrze;
Ada run-time kernel Green Hills Software INTEGRITY-178B RTOS GMART GSTART Lockheed Martin Boeing Rockwell Raytheon Joint Strike Fighter F-35 B-1B awionika Sikorsky S-92 F-16 Airbus A380 Boeing X-45 UCAV Airbus A400M
Ada run-time DDC-I DARTS C-130 Cassini analizator pyłu Sikorsky S-92
Ada run-time Aplikacje w Adzie GNARL GNU GNU Ada Ada Run-time Library Library GNULL GNULL (POSIX SAL SAL ;) ;))) POSIX POSIX Sprzęt Sprzęt i i system system operacyjny
Ada run-time - GNARL poprawność semantyczna (tasking) przyrostowe budowanie kodu (częściowa implementacja) modularność przenośność efektywność
Typy nieograniczone type Wektor is array (Integer range <>) of Float; subtype Wektor_3 is Wektor (1..3); subtype Wektor_11 is Wektor (1..11); X:Wektor(1..10);
Typy type Liczby_Rzymskie is ('I','V','X','L','C','D','M'); type Character...... -- ISO8859-1 'X' < 'L' --??? Character'('X') < 'L' -- NIE Liczby_Rzymskie'('X') < 'L' -- TAK
Typ String type String is (Positive range <>) of Character; A:String(1..3):= ('k','o','t'); B:String(1..3):= "kot"; C:String:= "kot"; D:String(1..3):= "pies"; --!! C:String:= "pies"; A:String(1..3):= ('k','o','t'); B:String(1..50); B(45..47):= A(1..3);
Record type MonthName is (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec); type Date is record Day : Integer range 1..31; Month : MonthName; Year : Integer := 2012; -- koniec swiata end record; A : Date := (12, Jun, 2012); B : Date := (Day => 13, Year => 1981, Month => Dec); C : Date := (Month => Jan, others => <>); C.Day := 22; Z : array(1..22) of Date; Z(2).Day := 22;
Funkcje function Test(X : Float) return Integer; function Test1(I, J, K : Date) return Float; function Test2(B : Date) return Boolean; function Test3 return Boolean; function Test(X : Float) return Integer is begin if X > 3.14 then return 1; else return 0; end if; end;
Funkcje przeciążanie tryb ''in'' wywołanie jako część wyrażenia wywołanie zawsze na kopii argumentów argumenty nie mogą być typami anonimowymi
Funkcje type Vector is array (Positive range <>) of Float; function Rev(A : Vector) return Vector is begin return Result : Vector(A'Range) do for I in A'Range loop Result(I) := A(A'First + A'Last - I); end loop; end return; end;
Procedury procedure BlaBla(A,B : in out Float; begin A :=... ; B :=... end; przeciążanie domyślny tryb ''in'' można wstawić instrukcję ''return'' C : Float) is
Procedury procedure BlaBla(A : Float := 1.345; B : Integer := 66; C : Positive := 1); BlaBla; BlaBla(2.234, 11); BlaBla(B => 11); BlaBla(2.22, C => 3); BlaBla(1.13, -2, 4);
Zadania Uruchomienie zadania następuje po zakończeniu opracowywania deklaracyjnej części zadania (utworzenie zadania wraz ze zmiennymi lokalnymi). Jeżeli w tej części zadania zostanie zgłoszony i nieobsłużony wyjątek, to zadanie zostanie uznane za zakończone. Jeżeli w jakimś bloku deklarowana jest pewna liczba zadań to są one aktywizowane przed wykonaniem pierwszej instrukcji bloku. Uruchomienie zadań tworzonych dynamicznie jest dokonywane po przydzieleniu pamięci ale przed powrotem z funkcji new. Zadanie zostaje zawieszone do momentu zakończenia aktywacji zadań potomnych.
Zadania task A is end; entry E; task body A is begin accept E; end; task B; task body B is begin A.E; end;
Zadania task type A(i:String) is entry E; end; tylko typy dyskretne i wskaźnikowe task body A is begin put(i); end;
Ada - zadania select accept A; or accept B; end select; selektywne oczekiwanie determinizm? select when <w1> => Jeśli oba zastrzeżenia będą miały wartość accept false to zgłoszony A; zostanie Program_Error Ewaluacja or zastrzeżeń występuje w momencie when wykonania <w2> instrukcji => select accept B; end select; wejście aktywne gdy warunek jest prawdą A'Count B'Count
Zadania, przeterminowanie select delay end select; [until] 1.0 select accept A; Ta loop gałąź wykona się jeśli w zadanym czasie [do accept select danego czasu] A; nie zostanie orwywołane żadne accept wejście. NewDelay(D : Time_Span) or do Odliczanie zaczyna się przy CurrentD instrukcji Ta := gałąź D; wykona się jeśli nie zostało accept select end; B; wywołane accept żadne wejście. B; else or delay 0.0 or else null; -- zrób coś --NextCycle := NextCycle + CurrentD; end select; delay until NextCycle; end loop; -- end select;
TAK czy NIE select accept A; or accept B; else C; end select; select accept A; or accept B; or delay 0.0; C; end select;
TAK czy NIE select accept A; or delay 10.0; C; end select select accept A; else delay 10.0; C; end select
TAK czy NIE select accept A; or delay 1.0; delay 1.0; end select select accept A; or delay 2.0; end select
Zadania select accept A; or accept B; or terminate; end select;
Ada - zadania select zad.wejscie; --... or delay 0.1; --... end select; select server.e(...); --... else --... end select;
Ada -zadania abort zadanie; zadanie jest usuwane z kolejek wejść może być odrzucona zadania zależne i podprogramy są przerywane
Monitor konstrukcja grupująca zm. dzielone dostęp do zm. tylko przez wywołanie funkcji monitora wzajemne wykluczanie w obszarze monitora element pasywny (mechanizm strukturalny) możliwe jest zawieszenie w obszarze monitora wraz z zezwoleniem na wejście w jego obszar innego procesu
Obiekty chronione odpowiednik monitora posiada funkcje procedury i wejścia funkcje służą tylko do odczytu procedury i wejścia mogą modyfikować o.ch. wejścia mogą posiadać bariery
Obiekty chronione protected SharedVariable is procedure Read(X: out integer); procedure Write(X: in integer); private V: integer := 0; end; protected body SharedVariable is procedure Read(X: out integer) is begin X := V; end; procedure Write(X: in integer) is begin V := X; end; end; end body;
Obiekty chronione protected SharedVariable is procedure Read(X: out integer); procedure Write(X: in integer); private V: integer := 0; end; protected body SharedVariable is procedure Read(X: out integer) is begin X := V; end; procedure Write(X: in integer) is begin V := X; end; end; end body;
Obiekty chronione - ograniczenia select accept entry call delay tworzenie/uruchomienie zadania podprogram zawierający powyższe
OOPWEB - synchronizacja protected Event is entry Wait; -- wait for the event to occur procedure Signal; -- signal that the event has occurred. private Occurred: Boolean := False; end Event; protected body Event is entry Wait when Occurred is begin Occurred := False; -- consume the signal end Wait; procedure Signal is begin Occurred := True; -- set Wait barrier True end Signal; end Event;
Producent konsument task body Producer is begin loop... -- generate a value Buffer.Put(New_Item); end loop; end Producer; task body Consumer is begin loop Buffer.Get(An_Item);... -- use a value end loop; end Consumer;
Producent konsument protected Buffer is entry Put(X: in Item); entry Get(X: out Item); private Data: Item; Full: Boolean := False; end; protected body Buffer is entry Put(X: in Item) when not Full is begin Data := X; Full := True; end Put; entry Get(X: out Item) when Full is begin X := Data; Full := False; end Get; end Buffer;
Wyjątki Constraint_Error Program_Error Storage_Error Tasking_Error
Wyjątki declare --... begin --... exception when Constraint_Error Program_Error =>... when Storage_Error... when others =>... end;
Wyjątki exception when error =>... raise buffer_error; when others =>... raise; end;
Wyjątki with Ada.Exceptions; use Ada.Exceptions; declare MyExc: exception; begin raise MyExc with "message"; exception when Event:MyExc => Put(Exception_Message(Event)); end;
Przerwania protected Sensor is procedure Int_Handler; pragma Attach_Handler(Int_Handler, InterruptID); private --...
Przerwania use Ada.Interrupts; protected Sensor is procedure Int_Handler; pragma Interrupt_Handler(Int_Handler); private... end; Attach_Handler(Sensor.Int_Handler'Access, IntID); procedure Exchange_Handler( OldHandler : out Parameterless_Handler, NewHandler : in Parameterless_Handler, Interrupt : in Interrupt_ID); procedure Detach_Handler(Interrupt : in Interrupt_ID);
Priorytety priorytety statyczne priorytety dynamiczne inwersja priorytetów
Priorytety with System; use System; task T1 is pragma priority(2); end; task type T(p : Priority) is end; pragma priority(p); protected V is --... pragma Priority(6); private --... end;
Priorytety T1 : T(2); -- typ zadaniowy i : Integer; --... Set_Priority(5, T1'Identity); i := Get_Priority(T1'Identity);
Zadanie cykliczne task type Cyclic(Pri : System.Priority; Cycle_Time : Positive) is pragma Priority(Pri); end; task body Cyclic is Next_Period : Ada.Real_Time.Time; Period : constant Ada.Real_Time.Time_Span := Ada.Real_Time.Microseconds(Cycle_Time); begin Next_Period := Ada.Real_Time.Clock + Period; loop delay until Next_Period; Next_Period := Next_Period + Period; -- TODO end loop; end;
Zadanie sporadyczne Ada.Synchronous_Task_Control SO : Suspension_Object; task type Sporadic(Pri : System.Priority) is end; pragma Priority(Pri); task body Sporadic is begin loop Suspend_Until_True(SO); -- Non-suspending sporadic response code end loop; end;
Typ prywatny package Complex_Numbers is type Complex is record Re,Im: Float; end record; I: constant Complex := (0.0,1.0); function "+"(X:Complex) return Complex; function "-"(X:Complex) return Complex; function "+"(X,Y:Complex) return Complex; function "-"(X,Y:Complex) return Complex; function "*"(X,Y:Complex) return Complex; end;
Typ prywatny package Complex_Numbers is type Complex is private; I: constant Complex; function "+"(X:Complex) return Complex; function "-"(X:Complex) return Complex; function "+"(X,Y:Complex) return Complex; function "-"(X,Y:Complex) return Complex; function "*"(X,Y:Complex) return Complex; function Cons(R,I:Float) return Complex; private type Complex is record Re,Im: Float; end record; I: constant Complex := (0.0,1.0); end;
Typ prywatny declare use Complex_Numbers; X,Y:Complex; begin X:= Cons(2.45,5.23); Y:= X + I;... end;
Typ prywatny package Complex_Numbers is type Complex is record Re,Im: Float; end record; I: constant Complex := (0.0,1.0); function "+"(X:Complex) return Complex; function "-"(X:Complex) return Complex; function "+"(X,Y:Complex) return Complex; function "-"(X,Y:Complex) return Complex; function "*"(X,Y:Complex) return Complex; end;
Typ prywatny package ComplexNumbers is type Complex is private; I : constant Complex; function "-"(X : Complex) return Complex; function "+"(X, Y : Complex) return Complex; function Comp(R, I : Float) return Complex; function Re(X : Complex) return Float; function Im(X : Complex) return Float; private type Complex is record RePart, ImPart : Float; end record; I : constant Complex := (0.0, 1.0); end;
Typ prywatny declare use Complex_Numbers; X,Y:Complex; begin X:= Cons(2.45,5.23); Y:= X + I;... end;
Typ ograniczony type T is limited private; type U is limited record... end record; tylko operacje zdefiniowane w specyfikacji pakietu, brak :=, =, i /= można implementować jako typ nieograniczony (część prywatna) całkowita kontrola nad obiektami danego typu
Ada - typy ograniczone type Stack is limited private; type Cell; type Cell_Ptr is access Cell; type Cell is record Next: Cell_Ptr; Value: Integer; end record; type Stack is new Cell_Ptr; function Make_One(X:Integer) return Stack is begin return new Cell'(null,X); end; S:Stack:=Make_One(4); -- OK S:= Make_One(4); -- OK?
Programowanie obiektowe możliwość definiowania jednego typu w kategoriach innego (rozszerzenie typu) możliwość dziedziczenia podstawowych operacji rodzica możliwość rozróżnienia danego typu danego obiektu w trakcie działania programu i wybrania dla niego właściwych operacji
Typy znakowany package Objects is type Object is tagged record X: Float; Y: Float; end record; function Distance(O:Object) return Float; function Area(O:Object) return Float; end Objects;
Typ znakowany with Objects; use Objects; package Shapes is type Circle is new Object with record R: Float; end record; function Area(C: Circle) return Float; type Point is new Object with null record; type Triangle is new Object with record A,B,C: Float; end record; function Area(T: Triangle) return Float; end Shapes;
Typ znakowany O: Object:=(1.3,5.3); C: Circle:=(3.5,1.0,4.6); T: Triangle; P: Point; O:=Object(C); C:=(O with 22.3); T:=(O with A=>3.2, B=>2.7, C=> 6.0); P:=(O with null record);
Typ znakowany type Cylinder is new Circle with record H: Float; end record; Cyl: Cylinder; Cyl:= (O with R=>3.14, H=>0.11); Cyl:= (C with H=>33.0); Cyl := (Object(T) with 3.33, 6.66);
Typ znakowany - 'Class T'Class -- unia wszystkich typów wyprowadzonych z T. wartości T'Class to T oraz wszystkie typy wyprowadzone z T wartość każdego typu wyprowadzonego z T może być konwertowana do typu T'Class rozmiar typu T'Class jest nieokreślony
Typ znakowany
Typ znakowany
Typ znakowany type Reservation_Ptr is access all Reservation'Class; type Cell is record Next: access Cell; Elem: Reservation_Ptr; end record;
Typ znakowany konwersja pomiędzy dwoma typami możliwa tylko w kierunku przodka konwersja z danego typu do typu klasowego dowolnego przodka jest dozwolona konwersja do typu klasowego, który nie jest przodkiem jest zabroniona konwersja z typu klasowego do typu należącego do klasy jest możliwa po podaniu danego typu konwersja pomiędzy typami klasowymi jest możliwa po podaniu typu klasy docelowej konwersja typów wskaźnikowych jest możliwa jeśli jest możliwa dla wskazywanych typów jeśli konwersja wymaga sprawdzenia w trakcie wykonania to nie może być to typ anonimowy
Typ znakowany type Person is abstract tagged record Birth:Date; end record; type Man is new Person with record Age: Integer; end record; type Woman is new Person with record Hair_Style:... ; end record; if P in Woman then... if P'Tag = Woman'Tag then... if P in Woman'Class then...
Typ abstrakcyjny package P is type T is abstract tagged record... end record; procedure Op(X:T) is abstract;... end P;
Typ abstrakcyjny nie można stworzyć obiektu typu abstrakcyjnego nie można wykonać metody typu abstrakcyjnego może posiadać komponenty składowe może posiadać zdefiniowane operacje
Typ kontrolowany Operacje podstawowe związane z typami kontrolowanymi: inicjalizacja po stworzeniu finalizacja przed unicestwieniem poprawka po przypisaniu
Typ kontrolowany declare A:T; begin A:=E Adjust(A)... end; -- create A, Initialize(A) --Finalize(A), copy value, -- Finalize(A)
Typ rodzajowy generic type Item is private; procedure Exchange(X,Y: in out Item); procedure Exchange(X,Y: in out Item) is T: Item; begin T:=X;X:=Y;Y:=T; end; procedure Swap is new Exchange(Float); procedure Swap is new Exchange(Integer); procedure Swap is new Exchange(Date);
Wywołanie operacji Op - operacja na typie T zdefiniowana w pakiecie P T - typ znakowany Op - operacja podstawowa lub klasowa X - pierwszy parametr Op P.Op(X,...); X.Op(...);
Kończenie zadań type Cause_Of_Termination is (Normal, Abnormal, Unhandled_Exception); type Termination_Handler is access protected procedure (Cause : Cause_Of_Termination; T : Ada.Task_Identification.Task_Id; X : Ada.Exceptions.Exception_Occurrence); procedure Set_Dependents_Fallback_Handler (Handler : Termination_Handler); function Current_Task_Fallback_Handler return Termination_Handler; procedure Set_Specific_Handler (T : Ada.Task_Identification.Task_Id; Handler : Termination_Handler); function Specific_Handler (T : Ada.Task_Identification.Task_Id) return Termination_Handler;
Kończenie zadań protected Deep_Trouble is procedure Last_Hope(Cause : Cause_Of_Termination; T : Ada.Task_Identification.Task_Id; X : Ada.Exceptions.Exception_Occurrence); end Deep_Trouble; -- Set_Specific_Handler(T'Identity, Deep_Trouble.Last_Hope'Access); Set_Dependents_Fallback_Handler( Deep_Trouble.Last_Hope'Access);
Ada.Task_Termination procedure Last_Hope(Cause : Cause_Of_Termination; T : Ada.Task_Identification.Task_Id; X : Ada.Exceptions.Exception_Occurrence) is begin case Cause is when Normal => null; when Abnormal => -- when Unhalted_Exception => -- end case; end;
Ada.Execution_Time.Timers procedure Set_Handler (TM : in out Timer; In_Time : Ada.Real_Time.Time_Span; Handler : Timer_Handler); procedure Set_Handler (TM : in out Timer; At_Time : CPU_Time; Handler : Timer_Handler); function Current_Handler (TM : Timer) return Timer_Handler; procedure Cancel_Handler (TM : in out Timer; Cancelled : out Boolean); function Time_Remaining (TM : Timer) return Ada.Real_Time.Time_Span;
Ada.Execution_Time.Timers My_Timer: Timer(My_Task'Identity'Access); Time_Max: CPU_Time:= Time_Of(2,Miliseconds(512)); -- protected Timer_Exec is procedure Alarm(TM:in out Timer); end; protected body Timer_Exec is procedure Alarm(TM:in out Timer) is begin Abort_Task(TM.T.all); end Alarm; end Control; -- Set_Handler(My_Timer,Time_Max,Timer_Exec.Alarm'Access);
Ada.Execution_Time.Timers protected Timer_Exec is procedure Alarm(TM:in out Timer); private procedure Kill(TM:in out Timer); end; protected body Timer_Exec is procedure Alarm(TM:in out Timer) is begin Set_Priority(Priority'First,TM.T.all); Set_Handler(TM,Miliseconds(512),Kill'Access); end Alarm; procedure Kill(TM:in out Timer) is begin Abort_Task(TM.T.all); end Kill; end Control; protected type Timer_Exec(MS_Time_To_Kill: Integer) is