如何检查任务是否在 Ada 中终止

How to check if task is terminated in Ada

我有任务 A 调用任务 B
在某些 pint 处,任务 B 已终止,但任务 A 不知道,现在调用已终止的任务 B.
由于任务 B 已终止,因此从任务 A 调用它会终止任务 A

如何检查任务 B 是否已从任务 A 终止?

如果重要的话,我正在使用 GNAT Programming Studio。
我可以在终止前创建一个由 B 设置的全局变量,但我宁愿从 A.

中找出 B 的状态

您可以检查 B'Terminated,请参阅 RM 9.9

if not B'Terminated then
   -- do something
end if;

以下示例使用“已终止”属性允许主任务确定一组任务何时完成。

------------------------------------------------------------------
-- Parallel Array Filling --
------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
with Ada.Calendar; use Ada.Calendar;

procedure Array_Fill is
   Start_Time : Time := Clock;
   Num_Tasks  : constant := 8;
   Slice_Size : constant Natural := 8_388_608;
   Max_Size   : constant Natural :=  Num_Tasks * Slice_Size -1;
   subtype Values is Natural range 0..10_000;

   type Big_Array is array(Natural range 0..Max_Size) of Integer;
   type Big_Access is access Big_Array;

   -- Instantiate the generic package Ada.Numerics.Discrete_Random
   -- to produce random numbers in the range of the subtype Values
   -- defined above
   package Rand_Nums is new Ada.Numerics.Discrete_Random(Values);
   use Rand_Nums;

   -- dynamically allocate the integer array, initializing all array
   -- elements to the lowest valid value for type Integer
   The_Array  : Big_Access := new Big_Array'(Others => Integer'First);

   task type Filler is
      -- Set_Low is a synchronization point between the main task and
      -- an instance of the task type Filler. This point allows the main
      -- task to send an integer value >= 0 directly to the Filler task
      Entry Set_Low(Item : in Natural);
   end Filler;

   task body Filler is
      Id         : Natural;
      Low_Index  : Natural;
      High_Index : Natural;
      Seed       : Generator;
   begin
      Reset(Seed);

      -- the Filler task waits for the main task to send a value to the
      -- entry Set_Low.
      accept Set_Low(Item : in Natural) do
         Id := Item;
      end Set_Low;

      Low_Index := Id * Slice_Size;
      High_Index := Low_Index + (Slice_Size - 1);

      for I in Low_Index..High_Index loop
         The_Array(I) := Random(Seed);
      end loop;
   end Filler;

   -- create an array type containing Num_Tasks of Filler tasks;
   type Task_List is array(Natural range 0..Num_tasks - 1) of Filler;

   -- Create an instance of the task array. The tasks start as soon
   -- as this array is created
   List       : Task_List;

begin -- begin the execution of the main task
   -- Send ID values to each instance of the Filler task in the array
   -- List.
   for I in Task_List'Range loop
      List(I).Set_Low(I);
   end loop;

   loop -- waits for all the tasks to terminate
      if List(0)'Terminated and then
        List(1)'Terminated and then
        List(2)'Terminated and then
        List(3)'Terminated and then
        List(4)'Terminated and then
        List(5)'Terminated and then
        List(6)'Terminated and then
        List(7)'Terminated then
         exit;  -- exit this loop
      end if;
   end loop;

   Put_Line("Elapsed time " & Duration'Image(Clock - Start_Time) & " seconds");
end Array_Fill;