好吧,Ada任务很新,让我感到困惑。我有一个受保护对象的经典问题,它将ID作为键存储事件。这个想法是生产者任务用传入事件填充它,并且一个或多个消费者任务需要等待直到给定id的事件到达,即,它们应该阻塞直到它存储在地图中,然后返回那个事件。
目前为止的结构如下:
package Reply_Storage is new Ada.Containers.Indefinite_Ordered_Maps
(Key_Type => Command_Id_Type,
Element_Type => Event_Type);
protected type Reply_Queue is
procedure Put (Event : Event_Type);
entry Take (Id : Command_Id_Type; Event : out Event_Type);
private
Storage : Reply_Storage.Map;
end Reply_Queue;
protected body Reply_Queue is
procedure Put (Event : Event_Type) is
Id : Command_Id_Type := Event_Command_Id (Event);
begin
Storage.Insert (Id, Event);
end Put;
entry Take (Id : Command_Id_Type; Event : out Event_Type)
when not Storage.Is_Empty is
begin
if Storage.Contains(Id) then
Event := Storage.Element (Id);
Storage.Delete (Id);
end if;
end Take;
end Reply_Queue;
基本上,当不是Storage.Is_Empty 时,我需要一个障碍,而不是,当条目体中的Storage.Contains(Id)时,我需要一个障碍 EM>。当然,这是不允许的,因为障碍的检查与入场呼叫无关。
但是如何实现所需的同步?
答案 0 :(得分:2)
所以,你需要的是一个入口系列(仅适用于离散类型),如下所示:
package Reply_Storage is new Ada.Containers.Indefinite_Ordered_Maps
(Key_Type => Command_Id_Type,
Element_Type => Event_Type);
protected type Reply_Queue is
procedure Put (Event : Event_Type);
entry Take (Command_Id_Type) (Event : out Event_Type); -- entry family
private
Storage : Reply_Storage.Map;
end Reply_Queue;
protected body Reply_Queue is
procedure Put (Event : Event_Type) is
Id : Command_Id_Type := Event_Command_Id (Event);
begin
Storage.Insert (Id, Event);
end Put;
entry Take (for Id in Command_Id_Type) (Event : out Event_Type) -- entry family
when Storage.Contains(Id) is -- family designator (entry index) in barrier
begin
Event := Storage.Element (Id);
Storage.Delete (Id);
end Take;
end Reply_Queue;