1

最初にコードでこの質問を説明しましょう:

with Ada.Text_IO;

procedure Test
is

   task type Serving_Task is
      entry Start;
   end Serving_Task;

   task body Serving_Task is begin
      accept Start;
      Ada.Text_IO.Put_Line ("Started");
      loop
         null; --  Blocking operation, eg. accepting on a socket.
         null; --  Processing on blocking operation's result.
      end loop;
      Ada.Text_IO.Put_Line ("Stopped");
   end Serving_Task;

   type Server is tagged limited record
      Serving : Serving_Task;
   end record;

   procedure Start
     (S : in out Server)
   is begin
      Ada.Text_IO.Put_Line ("Starting");
      S.Serving.Start;
   end Start;

   procedure Stop
     (S : in out Server)
   is begin
      Ada.Text_IO.Put_Line ("Stopping");
      -- TODO To implement.
   end Stop;

   Main_Server : Server;

begin
   Ada.Text_IO.Put_Line ("Calling Start");
   Start (Main_Server);
   delay 5.0;
   Ada.Text_IO.Put_Line ("Calling Stop");
   Stop (Main_Server);
end Test;

これは典型的なサーバー構成です。着信接続を受け入れるループを持つサーバータスクがあります。Stop私の質問は、型のプロシージャを実装するための最良の方法は何ですかServer

サービングタスクがソケットの受け入れをブロックするまで(またはブロック呼び出しの直前、つまり、タスクを終了する前に完全に処理された場合はすべての受け入れられた要求)ループを終了して、タスクが終了する前にクリーンアップできるようにします。

最初に頭に浮かぶのは追加です

select
   accept Stop;
or
   delay 0.1;
   exit;
end select;

ループの終わりに、しかしそれは各反復で0.1秒無駄になります。重要なようです。

RM、Lovelaceチュートリアル、ウィキブックスでいくつかの例を見てきましたが、実際には何も適切ではないようでした。

エイダでのそのような(私が信じるかなり一般的な)問題のベストプラクティスは何ですか?

そして答えは...

Marc C回答に基づくソリューションの例:https ://gist.github.com/3413017

4

2 に答える 2

2

elseバージョンが必要です:

loop
   -- blocking read from socket
   -- process the data received
   select
      accept Stop;
      exit;
   else
      null;
   end select;
end loop;
于 2012-08-20T11:31:09.513 に答える
1

私が通常これを設定する方法は、ソケットを直接プログラミングするのではなく、最初にAdaCoreのGNAT.Socketsパッケージを使用することです。(ソケット)select()関数(Check_Selectorとしてラップされている)を使用して、データがソケットで使用可能になったときに通知を受けるため、GNAT.Socketsは他の場所から呼び出すことができるAbort_Selector()プロシージャを提供します。Check_Selector()でタスクがブロックされた状態で、データが到着するのを待つ(Status = Completed)か、終了する時間であるというフラグ(Status = Aborted)を待ちます。

TOMI_4_AdaパッケージTCP_ConnectのMonitor_Connectionsプロシージャの開始(397〜416行目)を参照してください。Monitor_Connectionsは、タスクConnection_Monitoringから呼び出されます(469〜495行目)。

于 2012-08-20T12:34:51.197 に答える