ネストされた「その後中止」構造は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
(ループ内でアボートが発生する)、プログラムは正しく機能します。「abortthen」はライブラリ関数内にある可能性があるため、非常に危険だと思います。次に例を示します。
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;
このプログラムがこの奇妙な方法で動作する理由を誰かが説明できますか?
Adaの制御機能の非同期転送とリアルタイム仕様の比較で述べたように、「非同期selectステートメントはネストされたATCを正しく処理します。たとえば、内部の遅延が保留中に外部のトリガーステートメントの遅延が期限切れになった場合、内部遅延はキャンセルされ、ATCは内部中止可能部分から公布されます…」
以下のバリエーションABBBBC
は、予想どおりに印刷されます。外側のトリガーステートメントは、5秒のタイムアウトを指定します。ネストされたトリガーステートメントは、3秒のタイムアウトを指定します。後者の中止可能な部分は、その2番目のバジェットの1秒しか消費しないため、次の部分loop
は、外側のタイムアウトの前に4つの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;
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加