【问题标题】:ADA: multiple tasksADA:多项任务
【发布时间】:2013-06-08 12:51:16
【问题描述】:

我在 Ada 并发编程中遇到问题。我必须在 Ada 中编写一个简单的程序来创建 N 个相同类型的任务,其中 N 是来自键盘的输入。问题是我必须在编译之前知道 N ... 我试图声明一个单独的类型:

TYPE my_arr IS ARRAY(INTEGER RANGE <>) OF some_task;

以及稍后在主程序的 BEGIN 部​​分:

DECLARE arr: my_arr(1 .. N);

但我得到了错误

数组声明中不受约束的元素类型

这(我认为)意味着任务类型 some_task 的大小未知。 有人可以帮忙吗?

【问题讨论】:

  • 看看 some_task 的定义会有所帮助。例如,它有任何判别式吗?

标签: arrays task ada


【解决方案1】:

这是对原始答案的重写,现在我们知道任务类型在 问题是有区别的。

您正在通过没有默认值的“判别式”向每个任务传递一个值,这使得任务类型不受约束;如果不为判别式提供值,则无法声明该类型的对象(并且提供默认值也无济于事,因为一旦创建了对象,就无法更改判别式)。

一种常见的方法是使用访问类型:

with Ada.Integer_Text_IO;
with Ada.Text_IO;
procedure Maciek is
   task type T (Param : Integer);
   type T_P is access T;
   type My_Arr is array (Integer range <>) of T_P;
   task body T is
   begin
      Ada.Text_IO.Put_Line ("t" & Param'Img);
   end T;
   N, M : Integer;
begin
   Ada.Text_IO.Put ("number of tasks: ");
   Ada.Integer_Text_IO.Get (N);
   Ada.Text_IO.Put ("parameter: ");
   Ada.Integer_Text_IO.Get (M);
   declare
      --  Create an array of the required size and populate it with
      --  newly allocated T's, each constrained by the input
      --  parameter.
      Arr : My_Arr (1 .. N) := (others => new T (Param => M));
   begin
      null;
   end;
end Maciek;

您可能需要在完成newed 任务后解除分配;在上面的代码中,任务的内存在退出 declare 块时泄漏。

【讨论】:

  • 好的,它可以工作,但我必须将参数从键盘发送到任务。当我尝试写:任务类型 T(param: INTEGER) 我得到同样的错误......
  • (param: Integer) 是一个判别式,将使您的任务成为不受约束的类型。如果你真的需要,你可以为判别式添加一个默认值(参数:整数:= 0)
【解决方案2】:

在“声明块”中分配它们,或动态分配它们:

   type My_Arr is array (Integer range <>) of Some_Task;

   type My_Arr_Ptr is access My_Arr;

   Arr : My_Arr_Ptr;

begin
   -- Get the value of N

   -- Dynamic allocation
   Arr := new My_Arr(1 .. N);

   declare
      Arr_On_Stack : My_Arr(1 .. N);

   begin
      -- Do stuff
   end;

end;

【讨论】:

  • 我认为 Maciej 是在声明块中创建它们的?
  • 是的,我是,但我也尝试过使用指针。在这两种情况下都有一个问题:我必须向每个任务发送 1 个参数,当我尝试时我得到“数组声明中不受约束的元素类型”
【解决方案3】:

如果您在运行时确定需要多少个任务,您可以将其作为命令行参数传递。

with Ada.Text_IO; use ADA.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Command_Line;
with Ada.Strings;

procedure multiple_task is

    No_of_tasks : Integer := Integer'Value(Ada.Command_Line.Argument(1));

    task type Simple_tasks;

    task body Simple_tasks is
    begin
        Put_Line("I'm a simple task");
    end Simple_tasks;

    type task_array is array (Integer range <>) of Simple_tasks;

    Array_1 : task_array(1 .. No_of_tasks);

begin
   null;

end multiple_task;

并运行为

> multiple_task.exe 3
I'm a simple task
I'm a simple task
I'm a simple task

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多