てきとう

てきとう

タスクの寿命

ARM 9.3 Task Dependence - Termination of Tasksがよく解らなかった*1からとりあえず試してみたよメモ


before:

with Ada.Text_Io;
procedure Task_Test is
   task type A is
      entry S(Name:Character;Time:Duration);
   end A;
   task body A is
      N:Character;
      T:Duration;
   begin
      accept S(Name:Character;Time:Duration) do
         N:=Name;
         T:=Time;
      end S;
      delay T;
      Ada.Text_Io.Put(N);
   end A;
   type A_Acc is access all A;
   T:A_Acc;
begin
   declare
      subtype A_Acc_L is A_Acc;
      --type A_Acc_L is access all A;
      TL:A_Acc_L:=new A;             --A_Accとして扱われる
   begin
      TL.S('1', 1.0);
   end;
   T:=new A;
   T.S('2', 0.5);
end Task_Test;
% time ./task_test  
21
./task_test  0.00s user 0.02s system 1% cpu 1.084 total


after:

with Ada.Text_Io;
procedure Task_Test is
   task type A is
      entry S(Name:Character;Time:Duration);
   end A;
   task body A is
      N:Character;
      T:Duration;
   begin
      accept S(Name:Character;Time:Duration) do
         N:=Name;
         T:=Time;
      end S;
      delay T;
      Ada.Text_Io.Put(N);
   end A;
   type A_Acc is access all A;
   T:A_Acc;
begin
   declare
      --subtype A_Acc_L is A_Acc;
      type A_Acc_L is access all A;
      TL:A_Acc_L:=new A;
   begin
      TL.S('1', 1.0);
   end;
   T:=new A;
   T.S('2', 0.5);
end Task_Test;
% time ./task_test  
12
./task_test  0.00s user 0.02s system 1% cpu 1.561 total


なんということでしょう!(某番組風に)


access taskを宣言したレベルは、その型の変数に代入されたtaskのインスタンスが終わる(T'Terminated=True)まで待機するようです。
逆に言うと、無限ループしてるTaskが一つでもあれば元タスクは止まりません。
なので、14, 15行目をloop..end loop;で囲む、すなわち

      loop
         delay T;
         Ada.Text_Io.Put(N);
      end loop;

こうすると、前者(before:)では

% ./task_test
212212212212212212212212212212212212..

という感じ*2に、後者(after:)は

% ./task_test
111111111111111111111111111111111111..

という感じ*3になります。("T:=new A;"にはたどり着きません)

*1:ということにして読むの放棄した

*2:適当に編集してあります

*3:これまた適当に編集してあります