嵌套"然后中止"在Ada合法建筑?如果是,我可以正确使用它们吗?我有这段代码:
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
task TestTask is
end TestTask;
task body TestTask is
begin
select
delay 2.0;
Put_Line("C"); -- never executed
then abort
select
delay 5.0;
then abort
Put_Line("A");
delay 4.0;
end select;
loop
Put_Line("B");
delay 10.0;
end loop;
end select;
end TestTask;
begin
null;
end Main;
我希望这段代码应在2秒后退出。但相反,它会连续打印" B"没有延迟(它忽略了delay 10.0
)。它看起来代码的行为方式如下:
Put_Line("A")
并等待2秒delay 10.0
如果不是delay 4.0
我们插入delay 1.0
(然后在循环中发生中止),程序就能正常工作。我认为这是非常危险的,因为"然后中止"可以在库函数内部,例如:
procedure Main is
----- It's function from library -----
procedure Foo is
begin
select
delay 5.0;
then abort
Put_Line("A");
delay 4.0;
end select;
end;
---------------------------------------
task TestTask is
end TestTask;
task body TestTask is
begin
select
delay 2.0;
Put_Line("C"); -- never executed
then abort
Foo;
loop
Put_Line("B");
delay 10.0;
end loop;
end select;
end TestTask;
begin
null;
end Main;
有人可以解释为什么这个程序会以这种奇怪的方式运行吗?
答案 0 :(得分:3)
如A Comparison of the Asynchronous Transfer of Control Features in Ada and the Real-Time Specification中所述,“异步select语句正确处理嵌套的ATC。例如,如果外部触发语句的延迟在内部延迟挂起时到期,则内部延迟将被取消,并且ATC将从内部可挽回的部分颁布......“
以下变体按预期打印ABBBBC
。外部触发语句指定五秒超时;嵌套的触发语句指定三秒超时。由于后者的可中止部分仅消耗其第二预算的一秒,因此随后的loop
可以在外部超时之前打印四个B.将外部delay
更改为1.0
,以便重现示例中显示的效果。
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
task TestTask;
task body TestTask is
begin
select
delay 5.0;
Put("C");
then abort
select
delay 3.0;
then abort
Put("A");
delay 1.0;
end select;
loop
Put("B");
delay 1.0;
end loop;
end select;
end TestTask;
begin
null;
end Main;