让我先用代码说明这个问题:
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 教程和 Wikibook 中查看了一些示例,但似乎没有什么合适的。
在 Ada 中,此类(我相信相当普遍)问题的最佳实践是什么?
而答案是……
基于Marc C答案的示例解决方案:https ://gist.github.com/3413017