私はAdaを学習していますが、並行性モデルの理解にはいくつか問題があります。次のテストアプリケーションは、並行して動作する3つのタスクを作成し、単純に一連の数値を出力します。 entry
のないタスクを使用するとすべて問題ありませんが、エントリを使用するとプロシージャコールブロックが発生し、並行性はまったく発生しません。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;
私はすでに述べたように、私はP_EXECUTE_NO_ENTRY
を呼び出す場合、出力が乱れているとタスクはメインスレッドから切り離されています。一方、*P_EXECUTE_ENTRY(to : in Integer)
は、ブロッキングプロシージャコールにつながり、出力はタスクを使用しないアプリケーションのようです。
Adaで同時にエントリが実行されているタスクはどのようになっていますか?
さらに、タスクの割り当てを解除する必要がありますか?
あなたは 'new'でタスクを作成する必要はありません。また、タスクタイプのオブジェクトを宣言することもできます。 –