Ada (język programowania) - Ada (programming language)

Ada
Paradygmat Wieloparadygmat : ustrukturyzowany , imperatywny , zorientowany obiektowo
Rodzina Pascal
Zaprojektowany przez
  • MIL-STD-1815, Ada 83: Jean Ichbiah
  • Ada 95: Tucker Taft
  • Ada 2005: Tucker Taft
  • Ada 2012: Tucker Taft
Po raz pierwszy pojawiły się luty 1980 ; 41 lat temu ( 1980-02 )
Wersja stabilna
Ada 2012 TC1
Dyscyplina pisania statyczny , mocny , bezpieczny , mianownik
OS Wielo- lub wieloplatformowy
Rozszerzenia nazw plików .adb, .ads
Strona internetowa www .adaic .org
Główne wdrożenia
AdaCore GNAT (do bezpłatnego pobrania: https://www.adacore.com/download ), kompilator
Green Hills Software Optimizing Ada 95,
PTC, Inc. PTC ApexAda i PTC ObjectAda,
„MapuSoft Ada-C/C++ changer” ., dawniej znany jako „AdaMagic with C Intermediate”,
DDC-I Score
Dialekty
SPARK , profil Ravenscar
Wpływem
ALGOL 68 , Pascal , Simula 67 , C++ (Ada 95), Smalltalk (Ada 95), Modula-2 (Ada 95) Java (Ada 2005), Eiffel (Ada 2012)
Pod wpływem
C++ , Chapel , Drago , D , Eiffel , Griffin , Java , Nim , ParaSail , PL/SQL , PL/pgSQL , Python , Ruby , Seed7 , SPARforte, Sparkel , SQL/PSM , VHDL

Ada jest ustrukturyzowanym , statycznie typizowanym , imperatywnym i obiektowym językiem programowania wysokiego poziomu , wywodzącym się z Pascala i innych języków. Ma wbudowaną obsługę języka dla projektu kontraktowego (DbC), niezwykle silne typowanie , jawną współbieżność, zadania, synchroniczne przekazywanie wiadomości, chronione obiekty i niedeterminizm . Ada poprawia bezpieczeństwo kodu i łatwość konserwacji, używając kompilatora do wyszukiwania błędów na korzyść błędów w czasie wykonywania . Ada to międzynarodowa norma techniczna , zdefiniowana wspólnie przez Międzynarodową Organizację Normalizacyjną (ISO) i Międzynarodową Komisję Elektrotechniczną (IEC). Od 2020 r. standardem, zwanym nieformalnie Ada 2012, jest ISO/IEC 8652:2012.

Ada została pierwotnie zaprojektowana przez zespół kierowany przez francuskiego informatyka Jeana Ichbiaha z CII Honeywell Bull w ramach kontraktu z Departamentem Obrony Stanów Zjednoczonych (DoD) w latach 1977-1983, który miał zastąpić ponad 450 języków programowania używanych w tym czasie przez Departament Obrony. Ada została nazwana na cześć Ady Lovelace (1815–1852), która została uznana za pierwszą programistkę komputerową.

Cechy

Ada została pierwotnie zaprojektowana dla systemów wbudowanych i czasu rzeczywistego. Wersja Ada 95, zaprojektowana przez S. Tuckera Tafta z Intermetrics w latach 1992-1995, poprawiła obsługę programowania systemowego, numerycznego, finansowego i obiektowego (OOP).

Funkcje Ady obejmują: silne typowanie , modułowe mechanizmy programowania (pakiety), sprawdzanie w czasie wykonywania , przetwarzanie równoległe ( zadania , synchroniczne przekazywanie komunikatów , chronione obiekty i niedeterministyczne instrukcje SELECT ), obsługa wyjątków i generyki . Ada 95 dodała obsługę programowania obiektowego , w tym dynamiczną wysyłkę .

Składnia Ady minimalizuje wybór sposobów wykonywania podstawowych operacji i preferuje angielskie słowa kluczowe (takie jak „albo inaczej” i „a następnie”) od symboli (takich jak „||” i „&&”). Ada używa podstawowych operatorów arytmetycznych „+”, „-”, „*” i „/”, ale unika używania innych symboli. Bloki kodu są oddzielone słowami, takimi jak „declare”, „begin” i „end”, gdzie po „end” (w większości przypadków) następuje identyfikator bloku, który zamyka (np. if ... end if , pętla ... koniec pętli ). W przypadku bloków warunkowych pozwala to uniknąć zawieszania się, które mogłoby sparować się z niewłaściwym zagnieżdżonym wyrażeniem if w innych językach, takich jak C lub Java.

Ada jest przeznaczona do tworzenia bardzo dużych systemów oprogramowania. Pakiety Ada można skompilować osobno. Specyfikacje pakietu Ada (interfejs pakietu) można również skompilować osobno bez implementacji w celu sprawdzenia spójności. Umożliwia to wykrywanie problemów na wczesnym etapie projektowania, przed rozpoczęciem wdrożenia.

Obsługiwana jest duża liczba kontroli w czasie kompilacji, aby uniknąć błędów, które nie byłyby wykrywalne do czasu uruchomienia w niektórych innych językach lub wymagałyby dodania jawnych kontroli do kodu źródłowego. Na przykład składnia wymaga jawnie nazwanego zamknięcia bloków, aby zapobiec błędom spowodowanym niedopasowanymi tokenami końcowymi. Stosowanie się do silnego typowania umożliwia wykrywanie wielu typowych błędów oprogramowania (błędnych parametrów, naruszeń zakresu, nieprawidłowych odwołań, niezgodnych typów itp.) w czasie kompilacji lub w inny sposób w czasie wykonywania. Ponieważ współbieżność jest częścią specyfikacji języka, kompilator może w niektórych przypadkach wykryć potencjalne zakleszczenia. Kompilatory również często sprawdzają błędnie napisane identyfikatory, widoczność pakietów, nadmiarowe deklaracje itp. i mogą dostarczać ostrzeżenia i przydatne sugestie, jak naprawić błąd.

Ada obsługuje również kontrole w czasie wykonywania w celu ochrony przed dostępem do nieprzydzielonej pamięci, błędami przepełnienia bufora , naruszeniami zakresu, błędami „ off-by-one”, błędami dostępu do tablicy i innymi wykrywalnymi błędami. Te sprawdzenia można wyłączyć w celu zapewnienia wydajności środowiska wykonawczego, ale często można je wydajnie skompilować. Zawiera również udogodnienia ułatwiające weryfikację programu . Z tych powodów Ada jest szeroko stosowana w systemach krytycznych, gdzie każda anomalia może prowadzić do bardzo poważnych konsekwencji, np. przypadkowej śmierci, obrażeń lub poważnych strat finansowych. Przykładami systemów, w których wykorzystywana jest Ada, są awionika , kontrola ruchu lotniczego , koleje, bankowość, technika wojskowa i kosmiczna.

Dynamiczne zarządzanie pamięcią Ady jest na wysokim poziomie i bezpieczne dla typu. Ada nie ma wskaźników ogólnych ani nieopisanych ; ani nie deklaruje niejawnie żadnego typu wskaźnika. Zamiast tego cała alokacja pamięci dynamicznej i cofnięcie alokacji musi odbywać się za pośrednictwem jawnie zadeklarowanych typów dostępu . Każdy typ dostępu ma skojarzoną pulę pamięci, która obsługuje niskopoziomowe szczegóły zarządzania pamięcią; programista może użyć domyślnej puli pamięci lub zdefiniować nowe (jest to szczególnie istotne w przypadku Non-Uniform Memory Access ). Możliwe jest nawet zadeklarowanie kilku różnych typów dostępu, które oznaczają ten sam typ, ale używają różnych pul pamięci. Ponadto język zapewnia kontrole dostępności , zarówno w czasie kompilacji, jak i w czasie wykonywania, co zapewnia, że wartość dostępu nie może przeżyć typu obiektu, na który wskazuje.

Chociaż semantyka języka pozwala na automatyczne czyszczenie niedostępnych obiektów, większość implementacji nie obsługuje tego domyślnie, ponieważ spowodowałoby to nieprzewidywalne zachowanie w systemach czasu rzeczywistego. Ada obsługuje ograniczoną formę zarządzania pamięcią na podstawie regionu ; również kreatywne wykorzystanie puli pamięci może zapewnić ograniczoną formę automatycznego zbierania śmieci, ponieważ zniszczenie puli pamięci niszczy również wszystkie obiekty w puli.

Podwójny myślnik („--”), przypominający myślnik em , oznacza tekst komentarza. Komentarze zatrzymują się na końcu linii, aby zapobiec przypadkowemu unieważnieniu przez niezamknięte komentarze całych sekcji kodu źródłowego. Wyłączenie całego bloku kodu wymaga teraz przedrostka każdego wiersza (lub kolumny) osobno znakiem „--”. Chociaż wyraźnie oznacza to wyłączony kod kolumną powtarzających się „--” w dół strony, powoduje to, że eksperymentalne wyłączanie/ponowne włączanie dużych bloków jest bardziej rozciągniętym procesem.

Średnik (";") jest terminatorem instrukcji , a instrukcja null lub no-operation to null;. Pojedynczy ;bez oświadczenia o wypowiedzeniu jest niedozwolony.

W przeciwieństwie do większości standardów ISO , definicja języka Ada (znana jako Ada Reference Manual lub ARM , a czasami Language Reference Manual lub LRM ) jest treścią darmową . Jest to więc wspólny punkt odniesienia dla programistów Ady, nie tylko dla programistów implementujących kompilatory Ady. Oprócz podręcznika referencyjnego istnieje również obszerny dokument z uzasadnieniem, który wyjaśnia projekt języka i użycie różnych konstrukcji językowych. Ten dokument jest również szeroko używany przez programistów. Kiedy język został zrewidowany, napisano nowy dokument z uzasadnieniem.

Jednym z godnych uwagi darmowych narzędzi, które jest używane przez wielu programistów Ady, aby pomóc im w pisaniu kodu źródłowego Ady, jest GNAT Programming Studio , część GNU Compiler Collection .

Historia

W latach 70. amerykański Departament Obrony (DoD) zaniepokoił się liczbą różnych języków programowania używanych w projektach wbudowanych systemów komputerowych, z których wiele było przestarzałych lub zależnych od sprzętu, a żaden z nich nie wspierał bezpiecznego programowania modułowego. W 1975 roku grupa robocza The Wysoka Zamówienie Grupa Robocza Język (HOLWG), została utworzona z zamiarem zmniejszenia tej liczby poprzez znalezienie lub stworzenie języka programowania ogólnie nadaje się do dział i do Ministerstwa Obrony Wielkiej Brytanii wymagań „s. Po wielu iteracjach rozpoczynających się od oryginalnej propozycji Strawmana, ostateczny język programowania został nazwany Ada. Całkowita liczba języków programowania wysokiego poziomu używanych w takich projektach spadła z ponad 450 w 1983 r. do 37 w 1996 r.

Grupa robocza HOLWG opracowała wymagania językowe Steelmana , serię dokumentów określających wymagania, które według nich powinien spełniać język programowania. Wiele istniejących języków zostało formalnie zweryfikowanych, ale zespół doszedł do wniosku w 1977 r., że żaden istniejący język nie spełnia specyfikacji.

Augusta Ada King , hrabina Lovelace.

Wysłano zapytania ofertowe dotyczące nowego języka programowania i zatrudniono czterech wykonawców do opracowania swoich propozycji pod nazwami Red ( Intermetrics, kierowany przez Benjamina Brosgola), Zielony ( CII Honeywell Bull , kierowany przez Jeana Ichbiaha ), Blue ( SofTech , kierowany przez John Goodenough) i Yellow ( SRI International , kierowany przez Jaya Spitzena). W kwietniu 1978, po publicznej kontroli, propozycje czerwonych i zielonych przeszły do ​​następnej fazy. W maju 1979 roku wybrana została propozycja Green, zaprojektowana przez Jeana Ichbiaha z CII Honeywell Bull, i nazwana została Ada – od Augusta Ada, hrabiny Lovelace . Na tę propozycję wpłynął język LIS, który Ichbiah i jego grupa opracowali w latach siedemdziesiątych. Wstępny podręcznik referencyjny Ady został opublikowany w ACM SIGPLAN Notices w czerwcu 1979 roku. Podręcznik referencyjny Standardu Wojskowego został zatwierdzony 10 grudnia 1980 roku ( urodziny Ady Lovelace ) i otrzymał numer MIL-STD-1815 na cześć narodzin Ady Lovelace rok. W 1981 roku CAR Hoare wykorzystał swoją przemowę nagrodą Turinga, by skrytykować Adę za nadmierną złożoność, a tym samym niewiarygodność, ale później wydawał się wycofywać we wstępie, który napisał do podręcznika Ady.

Ada przyciągnęła wiele uwagi społeczności programistów jako całości na początku swojego istnienia. Jego zwolennicy i inni przewidywali, że może stać się dominującym językiem programowania ogólnego przeznaczenia, a nie tylko prac związanych z obronnością. Ichbiah publicznie oświadczył, że w ciągu dziesięciu lat pozostaną tylko dwa języki programowania: Ada i Lisp . Wczesne kompilatory Ada miały trudności z zaimplementowaniem dużego, złożonego języka, a wydajność zarówno w czasie kompilacji, jak i w czasie wykonywania była powolna, a narzędzia prymitywne. Producenci kompilatorów poświęcili większość swoich wysiłków na przejście ogromnego, wymaganego przez rząd pakietu walidacyjnego „ACVC”, który był wymagany w kolejnej nowatorskiej funkcji języka Ada. The Jargon File , słownik slangu hakerów komputerowych, który powstał w latach 1975–1983, zauważa we wpisie na temat Ady, że „dokładnie tego można się spodziewać, biorąc pod uwagę tego rodzaju poparcie ze strony fiat; zaprojektowane przez komisję… trudne w użyciu i ogólnie katastrofalny, wielomiliardowy bunt... Ada Lovelace... prawie na pewno zbladłaby, gdy ostatnio wykorzystano jej imię; najmilsze, co o tym powiedziano, to to, że prawdopodobnie istnieje język krzyczy, by wydostać się z jego ogromnej, słoniowej masy”.

Pierwszą sprawdzoną implementacją Ady był tłumacz NYU Ada/Ed, poświadczony 11 kwietnia 1983 r. NYU Ada/Ed jest zaimplementowany w języku wysokiego poziomu SETL . Kilka komercyjnych firm zaczęło oferować kompilatory Ada i powiązane narzędzia programistyczne, w tym Alsys , TeleSoft , DDC-I , Advanced Computer Techniques , Tartan Laboratories , TLD Systems i Verdix .

W 1991 roku Departament Obrony Stanów Zjednoczonych zaczął wymagać używania Ady ( nakaz Ady ) dla całego oprogramowania, chociaż często dopuszczano wyjątki od tej reguły. Mandat Departamentu Obrony Ada został skutecznie usunięty w 1997 r., gdy Departament Obrony zaczął stosować komercyjną technologię „z półki” ( COTS ). Podobne wymagania istniały w innych krajach NATO : Ada była wymagana dla systemów NATO obejmujących dowodzenie i kontrolę oraz inne funkcje, a Ada była zalecanym lub preferowanym językiem dla zastosowań związanych z obronnością w krajach takich jak Szwecja, Niemcy i Kanada.

Pod koniec lat 80. i na początku lat 90. kompilatory Ady poprawiły się pod względem wydajności, ale nadal istniały przeszkody uniemożliwiające pełne wykorzystanie możliwości Ady, w tym model zadań, który różnił się od tego, do którego przyzwyczaiło się większość programistów pracujących w czasie rzeczywistym.

Ze względu na krytyczne dla bezpieczeństwa funkcje Ady , jest ona obecnie wykorzystywana nie tylko w zastosowaniach wojskowych, ale także w projektach komercyjnych, w których błąd oprogramowania może mieć poważne konsekwencje, np. w awionice i kontroli ruchu lotniczego , rakietach komercyjnych, takich jak Ariane 4 i 5. , satelity i inne systemy kosmiczne, transport kolejowy i bankowość. Na przykład Airplane Information Management System , oprogramowanie systemu fly-by-wire w Boeingu 777 , zostało napisane w Adzie. Opracowany przez Honeywell Air Transport Systems we współpracy z konsultantami z DDC-I , stał się prawdopodobnie najbardziej znanym projektem Ada, cywilnym lub wojskowym. Kanadyjski zautomatyzowany system ruchu lotniczego został napisany w 1 milionie linii Ada ( liczba SLOC ). Zawierał zaawansowane przetwarzanie rozproszone , rozproszoną bazę danych Ada i projekt zorientowany obiektowo. Ada jest również wykorzystywana w innych systemach ruchu lotniczego, np. brytyjski system kontroli ruchu lotniczego nowej generacji Interim Future Area Control Tools Support (iFACTS) został zaprojektowany i wdrożony przy użyciu SPARK Ada. Jest również stosowany we francuskim systemie sygnalizacji kabinowej TVM w systemie kolei dużych prędkości TGV oraz w pociągach podmiejskich metra w Paryżu, Londynie, Hongkongu i Nowym Jorku.

Normalizacja

Język stał się standardem ANSI w 1983 roku ( ANSI/MIL-STD 1815A ), a po przetłumaczeniu na francuski i bez dalszych zmian w języku angielskim stał się standardem ISO w 1987 roku (ISO-8652:1987). Ta wersja języka jest powszechnie znana jako Ada 83, od daty jej przyjęcia przez ANSI, ale czasami jest również nazywana Ada 87, od daty jej przyjęcia przez ISO.

Ada 95, wspólny standard ISO/ANSI ( ISO-8652:1995 ) został opublikowany w lutym 1995, czyniąc Ada 95 pierwszym językiem programowania obiektowego w standardzie ISO. Aby pomóc w rewizji standardu i przyszłej akceptacji, Siły Powietrzne USA sfinansowały opracowanie kompilatora GNAT . Obecnie kompilator GNAT jest częścią GNU Compiler Collection .

Trwają prace nad ulepszaniem i aktualizacją zawartości technicznej języka Ada. Techniczne sprostowanie do Ada 95 zostało opublikowane w październiku 2001 r., a główna poprawka, ISO/IEC 8652:1995/Amd 1:2007 została opublikowana 9 marca 2007 r. Na konferencji Ada-Europe 2012 w Sztokholmie stowarzyszenie Ada Resource Association (ARA) i Ada-Europe ogłosiły zakończenie projektowania najnowszej wersji języka Ada i przedłożenie podręcznika referencyjnego Międzynarodowej Organizacji Normalizacyjnej (ISO) do zatwierdzenia. ISO/IEC 8652:2012 została opublikowana w grudniu 2012 roku.

Inne powiązane standardy obejmują ISO 8651-3 :1988 Systemy przetwarzania informacji — Grafika komputerowa — Wiązania językowe graficznego systemu jądra (GKS) — Część 3: Ada .

Konstrukcje językowe

Ada jest językiem programowania podobnym do ALGOL , zawierającym struktury kontrolne ze słowami zastrzeżonymi, takimi jak if , then , else , while , for i tak dalej. Jednak Ada posiada również wiele udogodnień strukturyzujących dane i inne abstrakcje, które nie były zawarte w oryginalnym ALGOL 60 , takie jak definicje typów , rekordy , wskaźniki , wyliczenia . Takie konstrukty zostały częściowo odziedziczone lub zainspirowane przez Pascala .

"Witaj świecie!" w Adzie

Typowym przykładem składni języka jest program Hello world : (hello.adb)

with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is
begin
   Put_Line ("Hello, world!");
end Hello;

Ten program można skompilować za pomocą ogólnodostępnego kompilatora open source GNAT , wykonując

gnatmake hello.adb

Typy danych

System typów Ady nie jest oparty na zestawie predefiniowanych typów pierwotnych, ale pozwala użytkownikom deklarować własne typy. Ta deklaracja z kolei nie opiera się na wewnętrznej reprezentacji typu, ale na opisie celu, który ma zostać osiągnięty. Umożliwia to kompilatorowi określenie odpowiedniego rozmiaru pamięci dla typu i sprawdzenie naruszeń definicji typu w czasie kompilacji iw czasie wykonywania (tj. naruszenia zakresu, przepełnienia bufora, spójność typów itp.). Ada obsługuje typy liczbowe zdefiniowane przez zakres, typy modulo, typy agregujące (rekordy i tablice) oraz typy wyliczeniowe. Typy dostępu definiują odwołanie do wystąpienia określonego typu; niewpisane wskaźniki są niedozwolone. Typy specjalne dostarczane przez język to typy zadań i typy chronione.

Na przykład data może być reprezentowana jako:

type Day_type   is range    1 ..   31;
type Month_type is range    1 ..   12;
type Year_type  is range 1800 .. 2100;
type Hours is mod 24;
type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);

type Date is
   record
     Day   : Day_type;
     Month : Month_type;
     Year  : Year_type;
   end record;

Typy można doprecyzować, deklarując podtypy :

subtype Working_Hours is Hours range 0 .. 12;            -- at most 12 Hours to work a day
subtype Working_Day is Weekday range Monday .. Friday;   -- Days to work

Work_Load: constant array(Working_Day) of Working_Hours  -- implicit type declaration
   := (Friday => 6, Monday => 4, others => 10);           -- lookup table for working hours with initialization

Typy mogą mieć modyfikatory, takie jak limited, abstract, private itp. Dostęp do typów prywatnych można uzyskać tylko, a typy ograniczone mogą być modyfikowane lub kopiowane tylko w zakresie pakietu, który je definiuje. Ada 95 dodaje kolejne funkcje rozszerzania typów zorientowanych obiektowo.

Struktury kontrolne

Ada jest ustrukturyzowanym językiem programowania , co oznacza, że ​​przepływ sterowania jest ustrukturyzowany w standardowe instrukcje. Obsługiwane są wszystkie standardowe konstrukcje i wczesne wychodzenie z głębokiego poziomu, więc użycie wspieranych również poleceń „ przejdź do ” jest rzadko potrzebne.

-- while a is not equal to b, loop.
while a /= b loop
  Ada.Text_IO.Put_Line ("Waiting");
end loop;

if a > b then
  Ada.Text_IO.Put_Line ("Condition met");
else
  Ada.Text_IO.Put_Line ("Condition not met");
end if;

for i in 1 .. 10 loop
  Ada.Text_IO.Put ("Iteration: ");
  Ada.Text_IO.Put (i);
  Ada.Text_IO.Put_Line;
end loop;

loop
  a := a + 1;
  exit when a = 10;
end loop;

case i is
  when 0 => Ada.Text_IO.Put ("zero");
  when 1 => Ada.Text_IO.Put ("one");
  when 2 => Ada.Text_IO.Put ("two");
  -- case statements have to cover all possible cases:
  when others => Ada.Text_IO.Put ("none of the above");
end case;

for aWeekday in Weekday'Range loop               -- loop over an enumeration
   Put_Line ( Weekday'Image(aWeekday) );         -- output string representation of an enumeration
   if aWeekday in Working_Day then               -- check of a subtype of an enumeration
      Put_Line ( " to work for " &
               Working_Hours'Image (Work_Load(aWeekday)) ); -- access into a lookup table
   end if;
end loop;

Pakiety, procedury i funkcje

Wśród części programu Ada znajdują się pakiety, procedury i funkcje.

Przykład: specyfikacja pakietu (example.ads)

package Example is
     type Number is range 1 .. 11;
     procedure Print_and_Increment (j: in out Number);
end Example;

Treść pakietu (przykład.adb)

with Ada.Text_IO;
package body Example is

  i : Number := Number'First;

  procedure Print_and_Increment (j: in out Number) is

    function Next (k: in Number) return Number is
    begin
      return k + 1;
    end Next;

  begin
    Ada.Text_IO.Put_Line ( "The total is: " & Number'Image(j) );
    j := Next (j);
  end Print_and_Increment;

-- package initialization executed when the package is elaborated
begin
  while i < Number'Last loop
    Print_and_Increment (i);
  end loop;
end Example;

Program ten można skompilować np. za pomocą ogólnodostępnego kompilatora open-source GNAT , wykonując

gnatmake -z example.adb

Pakiety, procedury i funkcje mogą być zagnieżdżane na dowolnej głębokości, a każdy z nich może być również logicznym blokiem zewnętrznym.

Każdy pakiet, procedura lub funkcja może mieć własne deklaracje stałych, typów, zmiennych i innych procedur, funkcji i pakietów, które można deklarować w dowolnej kolejności.

Konkurencja

Ada obsługuje języki współbieżności opartej na zadaniach. Podstawową jednostką współbieżną w Adzie jest task , który jest wbudowanym typem ograniczonym. Zadania są podzielone na dwie części – deklaracja zadania definiuje interfejs zadania (podobnie jak deklaracja typu), treść zadania określa realizację zadania. W zależności od implementacji zadania Ady są albo mapowane na wątki lub procesy systemu operacyjnego, albo są planowane wewnętrznie przez środowisko wykonawcze Ady.

Zadania mogą mieć wpisy do synchronizacji (forma synchronicznego przekazywania wiadomości ). Wpisy zadań są deklarowane w specyfikacji zadania. Każdy wpis zadania może mieć jedną lub więcej instrukcji akceptowania w treści zadania. Jeśli przepływ sterowania zadania osiągnie instrukcję accept, zadanie jest blokowane do momentu wywołania odpowiedniego wpisu przez inne zadanie (podobnie zadanie wywołujące jest blokowane, dopóki wywoływane zadanie nie osiągnie odpowiedniej instrukcji accept). Wpisy zadań mogą mieć parametry podobne do procedur, co pozwala zadaniom na synchroniczną wymianę danych. W połączeniu z instrukcjami select możliwe jest zdefiniowanie strażników na wyrażeniach akceptujących (podobnie jak komendy strzeżone Dijkstry ).

Ada oferuje również obiekty chronione do wzajemnego wykluczenia . Obiekty chronione są konstrukcją podobną do monitora , ale używają strażników zamiast zmiennych warunkowych do sygnalizacji (podobnie do warunkowych regionów krytycznych). Chronione obiekty łączą enkapsulację danych i bezpieczne wzajemne wykluczanie z monitorów oraz strażników wejścia z warunkowych obszarów krytycznych. Główną zaletą w porównaniu z klasycznymi monitorami jest to, że zmienne warunkowe nie są wymagane do sygnalizacji, co pozwala uniknąć potencjalnych zakleszczeń z powodu nieprawidłowej semantyki blokowania. Podobnie jak zadania, chroniony obiekt jest wbudowanym typem ograniczonym i ma również część deklaracji i treść.

Chroniony obiekt składa się z hermetyzowanych danych prywatnych (do których można uzyskać dostęp tylko z chronionego obiektu) oraz procedur, funkcji i wpisów, które gwarantują wzajemne wykluczanie się (z wyjątkiem funkcji, które muszą być wolne od skutków ubocznych i dlatego może działać jednocześnie z innymi funkcjami). Zadanie wywołujące chroniony obiekt jest blokowane, jeśli inne zadanie jest aktualnie wykonywane w tym samym chronionym obiekcie, i zwalniane, gdy to inne zadanie opuści chroniony obiekt. Zablokowane zadania są ustawiane w kolejce na chronionym obiekcie według czasu przybycia.

Wpisy obiektów chronionych są podobne do procedur, ale dodatkowo posiadają strażników . Jeśli strażnik ma wartość false, zadanie wywołujące jest blokowane i dodawane do kolejki tego wpisu; teraz do chronionego obiektu można dopuścić kolejne zadanie, ponieważ żadne zadanie nie jest aktualnie wykonywane wewnątrz chronionego obiektu. Strażnicy są ponownie oceniani za każdym razem, gdy zadanie opuszcza chroniony obiekt, ponieważ jest to jedyny moment, w którym ocena strażników może ulec zmianie.

Wywołania do wpisów mogą być kolejkowane do innych wpisów z tym samym podpisem. Zadanie, które jest umieszczone w kolejce, jest blokowane i dodawane do kolejki wpisu docelowego; oznacza to, że chroniony obiekt zostaje zwolniony i umożliwia przyjęcie kolejnego zadania.

Instrukcja select w Adzie może być wykorzystana do implementacji nieblokujących wywołań wejściowych i akceptuje, niedeterministyczny wybór wpisów (również ze strażnikami), time-outy i przerwania.

Poniższy przykład ilustruje niektóre koncepcje programowania współbieżnego w Adzie.

with Ada.Text_IO; use Ada.Text_IO;

procedure Traffic is

   type Airplane_ID is range 1..10;             -- 10 airplanes

   task type Airplane (ID: Airplane_ID);        -- task representing airplanes, with ID as initialisation parameter
   type Airplane_Access is access Airplane;     -- reference type to Airplane

   protected type Runway is                     -- the shared runway (protected to allow concurrent access)
      entry Assign_Aircraft (ID: Airplane_ID);  -- all entries are guaranteed mutually exclusive
      entry Cleared_Runway (ID: Airplane_ID);
      entry Wait_For_Clear;
   private
      Clear: Boolean := True;                   -- protected private data - generally more than only a flag...
   end Runway;
   type Runway_Access is access all Runway;

   -- the air traffic controller task takes requests for takeoff and landing
   task type Controller (My_Runway: Runway_Access) is
      -- task entries for synchronous message passing
      entry Request_Takeoff (ID: in Airplane_ID; Takeoff: out Runway_Access);
      entry Request_Approach(ID: in Airplane_ID; Approach: out Runway_Access);
   end Controller;

   --  allocation of instances
   Runway1    : aliased Runway;              -- instantiate a runway
   Controller1: Controller (Runway1'Access); -- and a controller to manage it

   ------ the implementations of the above types ------
   protected body Runway is
      entry Assign_Aircraft (ID: Airplane_ID)
 when Clear is   -- the entry guard - calling tasks are blocked until the condition is true
      begin
       Clear := False;
       Put_Line (Airplane_ID'Image (ID) & " on runway ");
      end;

      entry Cleared_Runway (ID: Airplane_ID)
 when not Clear is
      begin
         Clear := True;
         Put_Line (Airplane_ID'Image (ID) & " cleared runway ");
      end;

      entry Wait_For_Clear
 when Clear is
      begin
         null;      -- no need to do anything here - a task can only enter if "Clear" is true
      end;
   end Runway;

   task body Controller is
   begin
      loop
         My_Runway.Wait_For_Clear;   -- wait until runway is available (blocking call)
         select                      -- wait for two types of requests (whichever is runnable first)
            when Request_Approach'count = 0 =>  -- guard statement - only accept if there are no tasks queuing on Request_Approach
             accept Request_Takeoff (ID: in Airplane_ID; Takeoff: out Runway_Access)
             do                                 -- start of synchronized part
               My_Runway.Assign_Aircraft (ID);  -- reserve runway (potentially blocking call if protected object busy or entry guard false)
               Takeoff := My_Runway;            -- assign "out" parameter value to tell airplane which runway
             end Request_Takeoff;               -- end of the synchronised part
         or
            accept Request_Approach (ID: in Airplane_ID; Approach: out Runway_Access) do
               My_Runway.Assign_Aircraft (ID);
               Approach := My_Runway;
            end Request_Approach;
         or                          -- terminate if no tasks left who could call
            terminate;
         end select;
      end loop;
   end;

   task body Airplane is
      Rwy : Runway_Access;
   begin
      Controller1.Request_Takeoff (ID, Rwy); -- This call blocks until Controller task accepts and completes the accept block
      Put_Line (Airplane_ID'Image (ID) & "  taking off...");
      delay 2.0;
      Rwy.Cleared_Runway (ID);               -- call will not block as "Clear" in Rwy is now false and no other tasks should be inside protected object
      delay 5.0; -- fly around a bit...
      loop
         select   -- try to request a runway
            Controller1.Request_Approach (ID, Rwy); -- this is a blocking call - will run on controller reaching accept block and return on completion
            exit; -- if call returned we're clear for landing - leave select block and proceed...
         or
            delay 3.0;  -- timeout - if no answer in 3 seconds, do something else (everything in following block)
            Put_Line (Airplane_ID'Image (ID) & "   in holding pattern");  -- simply print a message
         end select;
      end loop;
      delay 4.0;  -- do landing approach...
      Put_Line (Airplane_ID'Image (ID) & "            touched down!");
      Rwy.Cleared_Runway (ID);  -- notify runway that we're done here.
   end;

   New_Airplane: Airplane_Access;

begin
   for I in Airplane_ID'Range loop  -- create a few airplane tasks
      New_Airplane := new Airplane (I); -- will start running directly after creation
      delay 4.0;
   end loop;
end Traffic;

Pragmas

Pragma to dyrektywa kompilatora, która przekazuje informacje do kompilatora, aby umożliwić określone manipulowanie skompilowanymi danymi wyjściowymi. Niektóre pragmy są wbudowane w język, podczas gdy inne są specyficzne dla implementacji.

Przykładami powszechnego użycia prag kompilatora może być wyłączenie pewnych funkcji,takich jak sprawdzanie typu w czasie wykonywania lub sprawdzanie granic tablicy indeksu dolnego, lub poinstruowanie kompilatora, aby wstawił kod obiektowy zamiast wywołania funkcji (jak C/C++ robi z funkcjami wbudowanymi ).

Generyki

Ada ma leki generyczne, odkąd po raz pierwszy została zaprojektowana w latach 1977-1980. Biblioteka standardowa używa generyków do świadczenia wielu usług. Ada 2005 dodaje do standardowej biblioteki obszerną generyczną bibliotekę kontenerów, która została zainspirowana standardową biblioteką szablonów C++ .

Jednostka ogólna to pakiet lub podprogram, który przyjmuje jeden lub więcej ogólnych parametrów formalnych .

Generyczny parametr formalny jest wartość, zmienna, stała, typ, podprogram lub nawet wystąpienie inny, wyznaczony, jednostka rodzajowy. W przypadku ogólnych typów formalnych składnia rozróżnia typy dyskretne, zmiennoprzecinkowe, stałoprzecinkowe, dostępowe (wskaźnikowe) itp. Niektóre parametry formalne mogą mieć wartości domyślne.

Aby utworzyć instancję jednostki generycznej, programista przekazuje aktualne parametry dla każdego formalu. Ogólna instancja zachowuje się wtedy jak każda inna jednostka. Możliwe jest tworzenie instancji jednostek ogólnych w czasie wykonywania , na przykład wewnątrz pętli.

Zobacz też

  • APSE – specyfikacja środowiska programistycznego wspierającego tworzenie oprogramowania w Ada
  • Profil Ravenscar — podzbiór funkcji zadań Ada zaprojektowanych z myślą o krytycznym dla bezpieczeństwa twardym przetwarzaniu w czasie rzeczywistym
  • SPARK (język programowania) – język programowania składający się z bardzo ograniczonego podzbioru Ady, z adnotacjami metainformacyjnymi opisującymi pożądane zachowanie komponentów i indywidualne wymagania wykonawcze

Bibliografia

Międzynarodowe standardy

Racjonalne uzasadnienie

Dokumenty te były publikowane w różnej formie, w tym drukowanej.

Książki

Archiwa

Zewnętrzne linki