等待项目到达受保护对象

时间:2016-08-23 17:05:55

标签: synchronization task blocking ada

好吧,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>。当然,这是不允许的,因为障碍的检查与入场呼叫无关。

但是如何实现所需的同步?

1 个答案:

答案 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;