Loops 如何在Ada中多次调用任务

Loops 如何在Ada中多次调用任务,loops,task,ada,Loops,Task,Ada,我尝试调用一个任务100次,但它不起作用,似乎我应该创建100个条目来完成。你能给我一些建议吗 我正在学习如何使用Ada任务:-) 带有Ada.Text\u IO;使用Ada.Text\u IO; 主要程序是 任务类型test1为 进入启动; 结束测试1; 任务体test1是 开始 接受启动; 放线(“哈哈”); 结束测试1; t1:test1; N:整数:=10; 开始 当N/=0循环时 t1.启动; N:=N-1; 端环; 端干管; E:\Ada Code\Simple\obj\main.

我尝试调用一个任务100次,但它不起作用,似乎我应该创建100个条目来完成。你能给我一些建议吗

我正在学习如何使用Ada任务:-)

带有Ada.Text\u IO;使用Ada.Text\u IO;
主要程序是
任务类型test1为
进入启动;
结束测试1;
任务体test1是
开始
接受启动;
放线(“哈哈”);
结束测试1;
t1:test1;
N:整数:=10;
开始
当N/=0循环时
t1.启动;
N:=N-1;
端环;
端干管;
E:\Ada Code\Simple\obj\main.exe 哈哈

引发任务分配错误
[2019-06-03 17:55:17]进程退出,状态为1,运行时间:01.00s

您的问题是,任务将在接受第一次会合后运行到完成。可以通过在任务正文中添加循环来避免此问题:

任务体test1是
开始
环
接受启动;
放线(“哈哈”);
端环;
结束测试1;
(事实上,大多数任务都会有这样的循环)

任务现在有一个无限循环,因此下一步是确保任务在主程序完成时终止。在这种情况下,您可以通过选择性接受:

任务体test1是
开始
环
选择
接受启动;
或
终止
终端选择;
放线(“哈哈”);
端环;
结束测试1;

一般来说,调用任务条目,向任务传递或从任务传递所需的数据,比启动另一个任务更有效。在启动和终止任务时会涉及到大量的开销。 为任务调用任务条目的另一种方法是使用受保护对象实现生产者-消费者模式

下面的生产者-消费者示例创建三个生产者和一个消费者。每个生产者向共享队列写入500000条消息。消费者使用生产者生成的所有消息

------------------------------------------------------------------
-- Producer / Consumer example using 3 producers and 1 consumer --
-- Matches the number of tasks to a 4-core processor            --
------------------------------------------------------------------
with Ada.Containers.Synchronized_Queue_Interfaces;
with Ada.Containers.Unbounded_Synchronized_Queues;
with Ada.Text_IO; use Ada.Text_IO;
With Ada.Calendar; use Ada.Calendar;
use Ada.Containers;

procedure PC_v3 is
   package Integer_Interface is new
     Synchronized_Queue_Interfaces(Element_Type => Integer);
   package Unbounded_Integer_Queues is new
     Unbounded_Synchronized_Queues(Queue_Interfaces => Integer_Interface);

   My_Queue      : Unbounded_Integer_Queues.Queue;
   Num_Producers : Constant := 3;
   Max_Produced  : constant := 500_000;
   Empty_Queue   : constant Count_Type := 0;
   Start_Time    : Time := Clock;

   -- The Counter protected object below is used to count the number of
   -- completed producers. This allows the consumer to know when all the
   -- data has been processed.
   ---------------------------------------------------------------------
   protected Counter is
      Procedure Task_Done;
      function All_Done return boolean;
   private
      Count : Natural := 0;
   end Counter;

   protected body Counter is
      procedure Task_Done is
      begin
         Count := Count + 1;
      end Task_Done;

      function All_Done return boolean is
      begin
         return Count = Num_Producers;
      end All_Done;
   end Counter;

   -- Define the producer task type.
   -- Producer is being defined as a task type to allow multiple instances
   -- of the producer to be easily created.
   ------------------------------------------------------------------------
   task type Producer;

   Task body Producer is
      Value : Positive := 1;
      Finis_Time : Time;
   begin
      loop
         My_Queue.Enqueue(Value);
         Value := Value + 1;
         if Value > Max_Produced then
            Counter.Task_Done;
            Finis_Time := Clock;
            Put_Line("Producer completed in" &
                       Duration'Image(Finis_Time - Start_Time) &
                       " seconds");
            exit;  -- exit the loop within the Producer task
         end if;
      end loop;
   end Producer;

   Read_Value : Integer;
   Done_Time  : Time;

   -- Create an array of producers. There are Num_Producers in this
   -- array. The Producer tasks start executing as soon as they are
   -- instantiated in the array.
   ----------------------------------------------------------------
   The_Producers : array(1..Num_Producers) of Producer;

begin
   -- Process the values in My_Queue until all producers are completed
   -- and the queue is empty.
   -- The program main task is being used as the consumer task.
   loop
      My_Queue.Dequeue(Read_Value);
      exit when Counter.All_Done and then My_Queue.Current_Use = Empty_Queue;
   end loop;
   -- Record the time stamp when all queue processing is done
   Done_Time := Clock;

   -- print out the execution statistics
   Put_Line("Queue element peak use:" & Count_Type'Image(My_Queue.Peak_Use));
   Put_Line("Elapsed time (seconds):" & Duration'Image(Done_Time - Start_Time));
end PC_V3;

如您所见,使用者会一直运行,直到所有数据都被消耗掉,而不知道有多少生产者正在运行,或者有多少消息正在生成。这比让每一位制作人为每一条消息打电话给消费者要有效得多。

非常感谢。事实上,我想迭代调用该任务。任务完成后,我会再次尝试调用它。您不能调用已完成的任务,因为没有任何东西可以处理调用。因此,在原始代码中出现了任务分配错误。是的,这就是问题所在。我希望完成一项任务。是否可以重新启动已完成的任务?无法重新启动任务。但是,您可以创建相同任务类型的另一个实例:
t2:test1或任务类型的数组:
T:test1的数组(1..100)此外,请遵循您的建议。我做了如下的事情,它也很有效<代码>带Ada.Text_IO的Ada;使用Ada.Text\u IO;程序Main是程序test1是任务类型test11是入口启动;结束试验11;任务体test11是begin-accept-Start;放线(“嘿嘿”);结束试验11;t11:test11;开始放线(“哈哈”);t11.启动;结束测试1;N:整数:=10;当N/=0时开始循环test1;N:=N-1;端环;端干管