J'apprends Ada et j'ai quelques problèmes pour comprendre les modèles de concurrence. L'application de test suivante doit créer trois tâches qui s'exécutent en parallèle et impriment simplement une série de nombres. Si j'utilise une tâche sans entry
alors tout va bien, mais si j'utilise des entrées les blocs d'appel de procédure et aucune concurrence peuvent se produire du tout. Je comprends qu'il y a une possibilité de réaliser une exclusion mutuelle et une exécution synchronisée, mais je ne suis pas capable de comprendre comment détacher les tâches afin qu'il soit même possible de créer plusieurs d'entre elles.Multithreading dans Ada
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;
Comme je l'ai déjà mentionné, si j'appelle P_EXECUTE_NO_ENTRY
la sortie est désordonnée et les tâches sont détachées du thread principal. D'autre part *P_EXECUTE_ENTRY(to : in Integer)
conduit à un appel de procédure de blocage et la sortie est comme une application qui n'utilise pas de tâches.
Comment les tâches avec des entrées sont-elles exécutées simultanément dans Ada?
De plus, dois-je également désallouer les tâches? (Des exemples provenant du Web ne l'ont pas fait)
Vous n'avez pas besoin de créer des tâches avec 'new'. Vous pouvez également déclarer simplement les objets d'un type de tâche. –