Ich lerne Ada und ich habe ein paar Probleme beim Verständnis der Gleichzeitigkeitsmodelle. Die folgende Testanwendung muss 3 Aufgaben erstellen, die parallel ausgeführt werden und einfach eine Reihe von Zahlen drucken. Wenn ich eine Aufgabe ohne entry
verwende, dann ist alles in Ordnung, aber wenn ich Einträge verwende, blockiert der Prozeduraufruf und es kann überhaupt keine Nebenläufigkeit passieren.Multithreading in Ada
Ich verstehe, dass es eine Möglichkeit gibt, gegenseitigen Ausschluss und synchronisierte Ausführung zu erreichen, aber ich bin nicht in der Lage zu verstehen, wie die Aufgaben gelöst werden, so dass es sogar möglich ist, mehrere von ihnen zu erstellen.
q_multithreading.ads:
package Q_MULTITHREADING is
task type TASK_LOOP is
end TASK_LOOP;
type TASK_LOOP_ACCESS is access TASK_LOOP;
--===========================================================================
task type TASK_ENTRY_LOOP is
entry P_ITERATE(to : in Integer);
end TASK_ENTRY_LOOP;
type TASK_ENTRY_LOOP_ACCESS is access TASK_ENTRY_LOOP;
--===========================================================================
procedure P_EXECUTE_NO_ENTRY;
procedure P_EXECUTE_ENTRY(to : in Integer);
end Q_MULTITHREADING;
q_multithreading.adb:
with Ada.Text_IO;
package body Q_MULTITHREADING is
V_ID_COUNTER : Integer := 1;
--===========================================================================
task body TASK_LOOP is
V_ID : Integer := -1;
begin
V_ID := V_ID_COUNTER;
V_ID_COUNTER := V_ID_COUNTER + 1;
for i in 1 .. 15 loop
delay 0.1;
Ada.Text_IO.Put_Line("[" & Integer'Image(V_ID) & "] " &
Integer'Image(i));
end loop;
V_ID_COUNTER := V_ID_COUNTER - 1;
end TASK_LOOP;
--===========================================================================
task body TASK_ENTRY_LOOP is
V_ID : Integer := -1;
begin
V_ID := V_ID_COUNTER;
V_ID_COUNTER := V_ID_COUNTER + 1;
accept P_ITERATE(to : in Integer) do
for i in 1 .. to loop
delay 0.1;
Ada.Text_IO.Put_Line("[" & Integer'Image(V_ID) & "] " &
Integer'Image(i));
end loop;
end P_ITERATE;
V_ID_COUNTER := V_ID_COUNTER - 1;
end TASK_ENTRY_LOOP;
--===========================================================================
procedure P_EXECUTE_NO_ENTRY is
V_TASK1, V_TASK2, V_TASK3 : TASK_LOOP_ACCESS;
begin
V_ID_COUNTER := 1;
Ada.Text_IO.Put_Line("Starting task 1 ...");
V_TASK1 := new TASK_LOOP;
Ada.Text_IO.Put_Line("Starting task 2 ...");
V_TASK2 := new TASK_LOOP;
Ada.Text_IO.Put_Line("Starting task 3 ...");
V_TASK3 := new TASK_LOOP;
end P_EXECUTE_NO_ENTRY;
--===========================================================================
procedure P_EXECUTE_ENTRY(to : in Integer) is
V_TASK1, V_TASK2, V_TASK3 : TASK_ENTRY_LOOP_ACCESS;
begin
V_ID_COUNTER := 1;
V_TASK1 := new TASK_ENTRY_LOOP;
Ada.Text_IO.Put_Line("Starting task 1 ...");
V_TASK1.P_ITERATE(to); -- blocking
V_TASK2 := new TASK_ENTRY_LOOP;
Ada.Text_IO.Put_Line("Starting task 2 ...");
V_TASK2.P_ITERATE(to - 5); -- blocking
V_TASK3 := new TASK_ENTRY_LOOP;
Ada.Text_IO.Put_Line("Starting task 3 ...");
V_TASK3.P_ITERATE(to + 3); -- blocking
end P_EXECUTE_ENTRY;
end Q_MULTITHREADING;
Wie schon erwähnt, wenn ich P_EXECUTE_NO_ENTRY
nennen die Ausgabe ungeordnet und die Aufgaben werden von der Haupt-Thread abgelöst. Auf der anderen Seite führt *P_EXECUTE_ENTRY(to : in Integer)
zu einem Blockierprozeduraufruf und die Ausgabe ist wie eine Anwendung, die keine Aufgaben verwendet.
Wie werden Aufgaben mit Einträgen in Ada gleichzeitig ausgeführt?
Muss ich die Aufgaben auch noch freigeben? (Beispiele aus dem Internet haben es nicht getan)
Sie müssen keine Aufgaben mit 'new' erstellen. Sie können auch einfach Objekte eines Aufgabentyps deklarieren. –