让我先用代码来说明这个问题:
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;
这是典型的服务器结构--有一个带有循环的服务器任务,它接受传入的连接。我的问题是-为Server
类型实现Server
过程的最佳方法是什么。
我希望它等待到服务任务在接受套接字时阻塞(或者就在阻塞调用之前,所以如果在结束任务之前完全处理了每个已接受的请求),然后退出循环,这样任务就可以在结束之前清理。
想到的第一件事就是增加
select
accept Stop;
or
delay 0.1;
exit;
end select;
在循环的末尾,但在每次迭代中都浪费了0.1秒。似乎意义重大。
我看过RM、Lovelace教程和Wikibook中的一些例子,但没有什么看起来真正合适。
对于Ada中的这类问题(我相信是相当常见的),最佳实践是什么?
和答案是.
基于马克C的回答:https://gist.github.com/3413017的示例解决方案
发布于 2012-08-20 04:34:51
我通常的设置方式是首先使用AdaCore的GNAT.Sockets包,而不是直接编程套接字。由于我将使用(套接字) select()函数(包装为Check_Selector)在套接字上可用数据时得到通知,所以GNAT.Sockets提供了一个可以从其他地方调用的Abort_Selector()过程。在Check_Selector()上的任务被阻塞后,我只需要等待数据到达(状态=已完成)或该退出的标志(状态=中止)。
请参阅Monitor_Connections包连接中的TOMI_4_Ada过程的开始(第397-416行)。Monitor_Connections是从任务Connection_Monitoring调用的(第469-495行)。
发布于 2012-08-20 03:31:09
您需要否则版本:
loop
-- blocking read from socket
-- process the data received
select
accept Stop;
exit;
else
null;
end select;
end loop;
https://stackoverflow.com/questions/12035670
复制相似问题