Concurrency 我们可以不以同步方式从池中运行每个任务吗?

Concurrency 我们可以不以同步方式从池中运行每个任务吗?,concurrency,ada,Concurrency,Ada,我是艾达的新手 我已经声明了我的新任务类型,并将其中三个存储在一个池中。然后,我想在循环中运行每个任务 预期的行为是同时执行所有这些操作 事实是,他们一个接一个地被处决。因此,任务(2)一执行,任务(1)就终止了。事实上,由于select约束,任务(2)将永远不会执行,因为它将终止 我的代码: with Counter; procedure Main is task type CounterTask is entry Execute(t:in Counter.Timeou

我是艾达的新手

我已经声明了我的新任务类型,并将其中三个存储在一个池中。然后,我想在循环中运行每个任务

预期的行为是同时执行所有这些操作

事实是,他们一个接一个地被处决。因此,任务(2)一执行,任务(1)就终止了。事实上,由于select约束,任务(2)将永远不会执行,因为它将终止

我的代码:

with Counter;
procedure Main is
    task type CounterTask is
        entry Execute(t:in Counter.Timeout; d:in Duration);
    end CounterTask;

    task body CounterTask is
        begin MyLoop: loop 
            select
                accept Execute(t:in Counter.Timeout;d:in Duration) do
                    Counter.Run(t, d);
                end Execute;
            or
                delay 2.0;
                exit;
            end select;
        end loop MyLoop;
    end CounterTask;
    tasks:Array(1..3) of CounterTask;
begin
    for i in Integer range 1..3 loop
        tasks(i).Execute(Counter.Timeout(10*i), Duration(0.5 * i));
    end loop;
end Main;

欢迎任何提示或想法

当主程序调用
accept
语句时

accept Execute(t:在计数器中。超时;d:在持续时间中)do
计数器运行(t,d);
结束执行;
它被阻止,直到
结束执行。您没有显示
计数器。运行
,但我猜其中有一个
延迟t
(或
d
?)

您需要将
Execute
的参数复制到accept语句中的本地任务变量,然后才调用
Counter.Run
;这样,主程序和
反任务
都可以自由进行

任务体反任务是
超时:计数器。超时;
Dur:持续时间;
开始
MyLoop:
环
选择
接受执行(t:在计数器中。超时;d:在持续时间中)do
超时时间:=T;
Dur:=D;
结束执行;
计数器运行(超时,Dur);
或
延迟2.0;
出口
终端选择;
端环MyLoop;
结束反任务;

<代码> > 除了使用<代码>计数器>运行< /代码>之外的代码>接受< /代码>块(如Simon Wright刚才所说),您可能还需要考虑使用同步屏障(参见):

with Counter;
with Ada.Synchronous_Barriers;

procedure Main is

  use Ada.Synchronous_Barriers;

  Num_Tasks : Positive := 3;

  Sync : Synchronous_Barrier (Num_Tasks);

  task type Counter_Task is
      entry Execute (T : in Counter.Timeout; D : in Duration);
  end Counter_Task;

  task body Counter_Task is
      Notified     : Boolean;
      The_Timeout  : Counter.Timeout;
      The_Duration : Duration;
  begin
      MyLoop : loop
        select

            accept Execute (T : in Counter.Timeout; D : in Duration) do
              The_Timeout  := T;
              The_Duration := D;
            end Execute;

            --  Synchronize tasks: wait until all 3 tasks have arrived at this point.
            Wait_For_Release (Sync, Notified);

            Counter.Run (The_Timeout, The_Duration);    
        or
            delay 2.0;
            exit;
        end select;
      end loop MyLoop;
  end Counter_Task;

  Tasks : array (1 .. Num_Tasks) of Counter_Task;

begin
  for K in Tasks'Range loop
      Tasks (K).Execute
        (Counter.Timeout (K * 10),
         Duration (Duration (0.5) * K));
  end loop;
end Main;