Ada select 多个条目
Ada select multiple entries
我正在寻找对多个条目进行 select 的方法。我有以下任务和 select 块。目的是在其他地方 运行 多 (2) 个任务,运行 直到一个完成,或者在一段时间后超时
task type t_startup_task is
entry start;
entry started;
end t_startup_task;
task body t_startup_task is
startup_sig : Boolean := False;
begin
accept start;
busy : loop -- wait for external flag to become true
status.read_signal (startup_sig);
if startup_sig then
exit busy;
end if;
delay 0.1;
end loop busy;
accept started;
end t_startup_task;
<...>
startup_task.start;
select
startup_task.started;
or
state.wait_done; -- other entry
abort startup_task;
return False;
or
delay 4.0;
end select;
但是,这会导致以下编译错误:
only allowed alternative in timed entry call is delay
"or" not allowed here
实际执行此操作的最佳方法是什么?
遗憾的是,您不能使用 select
语句来决定多个条目调用。但是,您可以使用它们来决定是否接受条目,因此具有三个任务的实现应该可以工作。
您仍然可以通过在最终入口调用中使用输出参数来获得您的 return 值。
task startup_task is
entry start;
entry wait_done;
entry signalled;
entry started (success : out boolean);
end startup_task;
-- This task waits upon your other entry, then calls the startup_task
-- entry once it has completed
task startup_wait is
entry start;
end startup_wait;
task body startup_wait is
begin
accept start;
state.wait_done;
startup_task.wait_done;
end startup_wait;
-- This task contains your busy loop and calls the startup_task
-- entry once it has completed
task startup_signal is
entry start;
end startup_signal;
task body startup_signal is
begin
accept start;
busy : loop -- wait for external flag to become true
status.read_signal (startup_sig);
if startup_sig then
exit busy;
end if;
delay 0.1;
end loop busy;
startup_task.signalled;
end startup_signal;
-- This task provides the functionality of your invalid select statement,
task body startup_task is
success : boolean := False;
begin
-- These start signals ensure that the subtasks wait for synchronisation
accept start;
startup_wait.start;
startup_signal.start;
select
accept signalled;
abort startup_wait;
success := True;
or
accept wait_done;
abort startup_signal;
or
delay 4.0
abort startup_wait;
abort startup_signal;
end select;
accept started (success);
end startup_task;
<...>
result : boolean;
begin
-- this block replaces your invalid select statement
startup_task.start;
startup_task.started(result);
return result;
end;
请注意,我尚未测试或编译此代码,但它应该提供解决方案的思路。
从技术上讲,该语言允许这样做:
select
delay 4.0;
...
then abort
select
Entry1;
...
then abort
Entry2;
...
end select;
end select;
这可能会做你想做的事。然而,最好的方法可能是让任务检查受保护的对象,并等待 PO 的条目:
protected Multi_Wait is
procedure Task1_Ready;
procedure Task2_Ready;
entry Wait_For_Either (Task_1 : out Boolean; Task_2 : out Boolean);
private -- Multi_Wait
Task1 : Boolean := False;
Task2 : Boolean := False;
end Multi_Wait;
那么你的代码就可以做到
select
Multi_Wait.Wait_For_Either (Task_1 => Task_1, Task_2 => Task_2);
if not Task_1 and Task_2 then
abort T1;
return False;
end if;
or
delay 4.0;
end select;
您的任务会调用适当的过程,而不是等待第二次入口调用。
我正在寻找对多个条目进行 select 的方法。我有以下任务和 select 块。目的是在其他地方 运行 多 (2) 个任务,运行 直到一个完成,或者在一段时间后超时
task type t_startup_task is
entry start;
entry started;
end t_startup_task;
task body t_startup_task is
startup_sig : Boolean := False;
begin
accept start;
busy : loop -- wait for external flag to become true
status.read_signal (startup_sig);
if startup_sig then
exit busy;
end if;
delay 0.1;
end loop busy;
accept started;
end t_startup_task;
<...>
startup_task.start;
select
startup_task.started;
or
state.wait_done; -- other entry
abort startup_task;
return False;
or
delay 4.0;
end select;
但是,这会导致以下编译错误:
only allowed alternative in timed entry call is delay
"or" not allowed here
实际执行此操作的最佳方法是什么?
遗憾的是,您不能使用 select
语句来决定多个条目调用。但是,您可以使用它们来决定是否接受条目,因此具有三个任务的实现应该可以工作。
您仍然可以通过在最终入口调用中使用输出参数来获得您的 return 值。
task startup_task is
entry start;
entry wait_done;
entry signalled;
entry started (success : out boolean);
end startup_task;
-- This task waits upon your other entry, then calls the startup_task
-- entry once it has completed
task startup_wait is
entry start;
end startup_wait;
task body startup_wait is
begin
accept start;
state.wait_done;
startup_task.wait_done;
end startup_wait;
-- This task contains your busy loop and calls the startup_task
-- entry once it has completed
task startup_signal is
entry start;
end startup_signal;
task body startup_signal is
begin
accept start;
busy : loop -- wait for external flag to become true
status.read_signal (startup_sig);
if startup_sig then
exit busy;
end if;
delay 0.1;
end loop busy;
startup_task.signalled;
end startup_signal;
-- This task provides the functionality of your invalid select statement,
task body startup_task is
success : boolean := False;
begin
-- These start signals ensure that the subtasks wait for synchronisation
accept start;
startup_wait.start;
startup_signal.start;
select
accept signalled;
abort startup_wait;
success := True;
or
accept wait_done;
abort startup_signal;
or
delay 4.0
abort startup_wait;
abort startup_signal;
end select;
accept started (success);
end startup_task;
<...>
result : boolean;
begin
-- this block replaces your invalid select statement
startup_task.start;
startup_task.started(result);
return result;
end;
请注意,我尚未测试或编译此代码,但它应该提供解决方案的思路。
从技术上讲,该语言允许这样做:
select
delay 4.0;
...
then abort
select
Entry1;
...
then abort
Entry2;
...
end select;
end select;
这可能会做你想做的事。然而,最好的方法可能是让任务检查受保护的对象,并等待 PO 的条目:
protected Multi_Wait is
procedure Task1_Ready;
procedure Task2_Ready;
entry Wait_For_Either (Task_1 : out Boolean; Task_2 : out Boolean);
private -- Multi_Wait
Task1 : Boolean := False;
Task2 : Boolean := False;
end Multi_Wait;
那么你的代码就可以做到
select
Multi_Wait.Wait_For_Either (Task_1 => Task_1, Task_2 => Task_2);
if not Task_1 and Task_2 then
abort T1;
return False;
end if;
or
delay 4.0;
end select;
您的任务会调用适当的过程,而不是等待第二次入口调用。