我们可以 运行 池中的每个任务不是以同步方式吗?
Can we run every task from a pool not in a synchronous manner?
我是 Ada 新手。
我已经声明了我的新任务类型,并将其中三个存储在一个池中。然后,我想运行循环中的每个任务。
预期的行为是所有这些都同时执行。
实际情况是,他们一个接一个被处决。因此,tasks(2) 刚一执行完,tasks(1) 就终止了。事实上,task(2) 将永远不会被执行,因为它由于 select 约束而终止。
我的代码:
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:in Counter.Timeout;d:in Duration) do
Counter.Run(t, d);
end Execute;
直到 end Execute
才被阻止。你没有显示Counter.Run
,但我猜那里有一个delay t
(或d
?)。
需要将Execute
的参数复制到accept语句中的局部任务变量中,然后才调用Counter.Run
;这样,主程序和 Countertask
都可以自由进行。
task body CounterTask is
Timeout : Counter.Timeout;
Dur : Duration;
begin
MyLoop:
loop
select
accept Execute(t:in Counter.Timeout;d:in Duration) do
Timeout := T;
Dur := D;
end Execute;
Counter.Run (Timeout, Dur);
or
delay 2.0;
exit;
end select;
end loop MyLoop;
end CounterTask;
除了将 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;
我是 Ada 新手。
我已经声明了我的新任务类型,并将其中三个存储在一个池中。然后,我想运行循环中的每个任务。
预期的行为是所有这些都同时执行。
实际情况是,他们一个接一个被处决。因此,tasks(2) 刚一执行完,tasks(1) 就终止了。事实上,task(2) 将永远不会被执行,因为它由于 select 约束而终止。
我的代码:
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:in Counter.Timeout;d:in Duration) do
Counter.Run(t, d);
end Execute;
直到 end Execute
才被阻止。你没有显示Counter.Run
,但我猜那里有一个delay t
(或d
?)。
需要将Execute
的参数复制到accept语句中的局部任务变量中,然后才调用Counter.Run
;这样,主程序和 Countertask
都可以自由进行。
task body CounterTask is
Timeout : Counter.Timeout;
Dur : Duration;
begin
MyLoop:
loop
select
accept Execute(t:in Counter.Timeout;d:in Duration) do
Timeout := T;
Dur := D;
end Execute;
Counter.Run (Timeout, Dur);
or
delay 2.0;
exit;
end select;
end loop MyLoop;
end CounterTask;
除了将 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;