Napisać działający kod, w którym...:
w dedykowanym zadaniu odbywają się czasochłonne obliczenia numeryczne polegające (najogólniej mówiąc) na wyznaczaniu coraz lepszego przybliżenia poszukiwanej wartości. Niestety dokładne wyznaczenie tej wartości trwałoby nieskończenie długo, więc w jakimś momencie obliczenia te trzeba w końcu przerwać i zadowolić się ostatnio wyznaczoną liczbą.
Należy zatem zaimplementować obiekt (może task, może protected?) udostępniający następujące procedury (/wejścia?):
Start_Calc(Init_Value: in Integer);
--rozpoczyna wykonywanie obliczen (dla podanej wartosci poczatkowej)
Get_Result(The_Result: out Integer);
--wymusza przerwanie obliczen. Parametr odbiera wynik obliczen
tak, aby w programie głównym następujące wywołania spowodowały odpowiednio: rozpoczęcie wykonywania obliczeń (podany parametr ustawia wartość początkowego przybliżenia poszukiwanej wartości) oraz wymuszenie przerwania obliczeń i odebranie wyznaczonej wartości:
C.Start_Calc(123); -- uruchomienie obliczen numerycznych
C.Get_Result(V); -- TERAZ potrzebny jest wynik. Przerwij obliczenia i daj, co masz.
Dodatkowe wymaganie na ocenę powyżej 3: nie wolno ingerować w ciało pętli wykonującej obliczenia (innymi słowy: między loop i end loop mają znaleźć się tylko te dwie linijki umieszczone w kodzie poniżej). Przerywanie wykonywania obliczeń trzeba wtedy zrobić jakoś poza ciałem pętli...
Rozwiązanie ma się znaleźć w katalogu nazwanym od swojego nazwiska. Niech w katalogu tym będą również wszystkie dodatkowe, wykorzystywane moduły.
W rozwiązaniu warto/należy oprzeć się na poniższym kodzie (tzn. kod ten uzupełnić, i/lub zmodyfikować...) :
with Ada.Text_IO; use Ada.Text_IO; -- + ew. inne pomocne moduly ...??...
procedure tresc is
--stosowne definicje typow zadaniowych i/lub chronionych, w tym:
... type Calculator is
--gdzies wewnatrz musi znalezc sie niniejsza petla, ktora wykonuje
--(symuluje wykonywanie) owe zlozone obliczenia numeryczne
--{parametr w Start_Calc ustala poczatkowa wartosc zmiennej Wynik_Obliczen}
loop
delay 0.0001; -- symuluje czas wykonywania obliczen
Wynik_Obliczen := (Wynik_Obliczen + 1) mod 123456; --"obliczenia"
end loop;
--... i w jakis sposob na sygnal Get_Result petla ta ma byc przerwana,
--a wartosc zmiennej Wynik_Obliczen ma byc zwrocona na zewnatrz
--program glowny:
C: Calculator; --'obiekt' odpowiadajacy za wykonanie obliczen
V: Integer;
begin
C.Start_Calc(123); -- uruchomienie obliczen numerycznych
delay 1.234; -- czas wyczekiwania. Obliczenia trwaja...
C.Get_Result(V); -- TERAZ potrzebny jest wynik. Przerwij obliczenia i daj, co masz.
Put_Line("Wynik obliczen: " & Integer'Image(V)); --wyswietlenie wyniku
end tresc;
with Ada.Text_IO;
use Ada.Text_IO; -- + ew. inne pomocne moduly ...??...
with Ada.Strings.Unbounded;
use Ada.Strings.Unbounded;
procedure tresc is
Wynik_Obliczen : Integer := 0; -- zmienna przechowyjaca wyniki obliczen ( nie wymaga wzajemnego wykluczania)
--stosowne definicje typow zadaniowych i/lub chronionych, w tym:
task type Calculator is
entry Start_Calc (
start : in integer);
entry Get_Result (
result : out integer);
end Calculator;
task type TaskLiczacy is
end TaskLiczacy;
type TaskLiczacyPtr is access TaskLiczacy;
task body TaskLiczacy is
begin
--Ada.Text_IO.put_line("Start tasku liczacego");
loop
delay 0.0001; -- symuluje czas wykonywania obliczen
Wynik_Obliczen := (Wynik_Obliczen + 1) mod 123456; --"obliczenia"
end loop;
end TaskLiczacy;
--gdzies wewnatrz musi znalezc sie niniejsza petla, ktora wykonuje
--(symuluje wykonywanie) owe zlozone obliczenia numeryczne
--{parametr w Start_Calc ustala poczatkowa wartosc zmiennej Wynik_Obliczen}
task body Calculator is
t : TaskLiczacyPtr;
begin
accept start_calc (
start : in integer) do
wynik_obliczen := start; -- ustawienie poczatkowej wartosci obliczen
--Ada.Text_IO.put_line("start_calc");
end start_calc;
t := new TaskLiczacy; -- powolanie tasku liczacego
accept get_result (
result : out integer) do
result := wynik_obliczen; -- zwracamy wynik
end get_result;
abort t.all; -- task liczacy juz niepotrzebny
end Calculator;
--... i w jakis sposob na sygnal Get_Result petla ta ma byc przerwana,
--a wartosc zmiennej Wynik_Obliczen ma byc zwrocona na zewnatrz
--program glowny:
C : Calculator; --'obiekt' odpowiadajacy za wykonanie obliczen
V : Integer;
begin
C.Start_Calc(123); -- uruchomienie obliczen numerycznych
delay 1.234; -- czas wyczekiwania. Obliczenia trwaja...
C.Get_Result(V); -- TERAZ potrzebny jest wynik. Przerwij obliczenia i daj, co masz.
Put_Line("Wynik obliczen: " & Integer'Image(V)); --wyswietlenie wyniku
end tresc;
with Ada.Text_IO; use Ada.Text_IO; -- + ew. inne pomocne moduly ...??...
procedure tresc is
--stosowne definicje typow zadaniowych i/lub chronionych, w tym:
Wynik_Obliczen : Integer := 0;
task type Clc is
entry Init(x : in Integer);
end Clc;
task body Clc is
--Wynik_Obliczen : Integer := 0;
begin
accept Init(x : in Integer) do
Wynik_Obliczen := x;
end Init;
loop
delay 0.0001; -- symuluje czas wykonywania obliczen
Wynik_Obliczen := (Wynik_Obliczen + 1) mod 123456; --"obliczenia"
end loop;
end Clc;
type Clc_Ptr is access Clc;
protected type Calculator is
procedure Get_Result(w : out Integer);
procedure Start_Calc(x : in Integer);
private
--Wynik_Obliczen : Integer := 0;
Licznik : Clc_Ptr;
end Calculator;
protected body Calculator is
--gdzies wewnatrz musi znalezc sie niniejsza petla, ktora wykonuje
--(symuluje wykonywanie) owe zlozone obliczenia numeryczne
--{parametr w Start_Calc ustala poczatkowa wartosc zmiennej Wynik_Obliczen}
procedure Start_Calc(x : in Integer) is
begin
Wynik_Obliczen := x;
Licznik := new Clc;
Licznik.init(x);
end Start_Calc;
procedure Get_Result(w : out Integer) is
begin
abort Licznik.all;
w := Wynik_Obliczen;
end Get_Result;
--... i w jakis sposob na sygnal Get_Result petla ta ma byc przerwana,
--a wartosc zmiennej Wynik_Obliczen ma byc zwrocona na zewnatrz
end Calculator;
--program glowny:
C: Calculator; --'obiekt' odpowiadajacy za wykonanie obliczen
V: Integer;
begin
C.Start_Calc(123); -- uruchomienie obliczen numerycznych
delay 0.234; -- czas wyczekiwania. Obliczenia trwaja...
C.Get_Result(V); -- TERAZ potrzebny jest wynik. Przerwij obliczenia i daj, co masz.
Put_Line("Wynik obliczen: " & Integer'Image(V)); --wyswietlenie wyniku
end tresc;
with Ada.Text_Io;
use Ada.Text_Io; -- + ew. inne pomocne moduly ...??...
procedure Zadanie4 is
--stosowne definicje typow zadaniowych i/lub chronionych, w tym:
task type Calculator is
entry Start_Calc (
Init_Value : in Integer );
entry Get_Result (
The_Result : out Integer );
end Calculator;
task body Calculator is
Wynik_Obliczen : Integer;
task Calculate is
entry Start (
Poczatkowa : in Integer );
end Calculate;
task body Calculate is
--gdzies wewnatrz musi znalezc sie niniejsza petla, ktora wykonuje
--(symuluje wykonywanie) owe zlozone obliczenia numeryczne
--{parametr w Start_Calc ustala poczatkowa wartosc zmiennej Wynik_Obliczen}
begin
accept Start (
Poczatkowa : in Integer ) do
Wynik_Obliczen := Poczatkowa;
end Start;
loop
delay 0.0001; -- symuluje czas wykonywania obliczen
Wynik_Obliczen := (Wynik_Obliczen + 1) mod 123456;
--"obliczenia"
end loop;
end Calculate;
Koniec : Boolean := False;
begin
loop
select
accept Start_Calc (
Init_Value : in Integer ) do
Calculate.Start(Init_Value);
end Start_Calc;
or
accept Get_Result (
The_Result : out Integer ) do
The_Result := Wynik_Obliczen;
abort Calculate;
Koniec := True;
end Get_Result;
end select;
exit when Koniec = True;
end loop;
end Calculator;
--... i w jakis sposob na sygnal Get_Result petla ta ma byc przerwana,
--a wartosc zmiennej Wynik_Obliczen ma byc zwrocona na zewnatrz
--program glowny:
C : Calculator; --'obiekt' odpowiadajacy za wykonanie obliczen
V : Integer;
begin
C.Start_Calc(123); -- uruchomienie obliczen numerycznych
delay 1.234; -- czas wyczekiwania. Obliczenia trwaja...
C.Get_Result(V);
-- TERAZ potrzebny jest wynik. Przerwij obliczenia i daj, co masz.
Put_Line("Wynik obliczen: " & Integer'Image(V)); --wyswietlenie wyniku
end Zadanie4;