我是Ada的新手。
我已经声明了新的任务类型,并将其中三个存储在一个池中。然后,我想循环运行每个任务。
预期的行为是它们全部同时执行。
现实是,它们一个接一个地执行。因此,任务(2)的执行不会早于任务(1)的终止。实际上,由于选择约束,task(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;
任何提示或想法都将受到欢迎!
答案 0 :(得分:6)
主程序调用{{1}}语句时
accept
它被阻止直到accept Execute(t:in Counter.Timeout;d:in Duration) do
Counter.Run(t, d);
end Execute;
。您没有显示end Execute
,但我想其中有一个Counter.Run
(或delay t
?)。
您需要将d
的参数复制到accept语句中的本地任务变量,然后才调用Execute
;这样,主程序和Counter.Run
都可以自由进行。
Countertask
答案 1 :(得分:2)
除了将Counter.Run
从accept
块中移除(正如Simon Wright所说)之外,您可能还需要考虑使用同步屏障(另请参见ARM D.10.1):
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;