餐饮哲学家问题 Ada- 实现 ID 分配器 [英] Dining Philosopher problem Ada- Implementing ID Dispenser

查看:13
本文介绍了餐饮哲学家问题 Ada- 实现 ID 分配器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码,与哲学家就餐问题有关.我对 Ada 很陌生,所以不确定如何实现 Id_Dispenser 包.

I have the following code, related to the dining philosopher problem. I am very new to Ada so am not sure about how to implement the Id_Dispenser package.

with Ada.Text_IO;  use Ada.Text_IO;
with Id_Dispenser;
with Semaphores;   use Semaphores;

procedure Philos is

   No_of_Philos : constant Positive := 5; -- Number of philosophers
   Meditation   : constant Duration := 0.0;

   type Table_Ix is mod No_of_Philos;

   Forks : array (Table_Ix) of Binary_Semaphore (Initially_Available => True);

   package Index_Dispenser is new Id_Dispenser (Element => Table_Ix);
   use Index_Dispenser;

   task type Philo;
   task body Philo is

      Philo_Nr : Table_Ix; -- Philisopher number

   begin
      Dispenser.Draw_Id (Id => Philo_Nr);
      Put_Line ("Philosopher" & Table_Ix'Image (Philo_Nr) & " looks for forks.");
      Forks (Philo_Nr).Wait; delay Meditation; Forks (Philo_Nr + 1).Wait;
      Put_Line ("Philosopher" & Table_Ix'Image (Philo_Nr) & " eats.");
      Forks (Philo_Nr).Signal; Forks (Philo_Nr + 1).Signal;
      Put_Line ("Philosopher" & Table_Ix'Image (Philo_Nr) & " dropped forks.");
   end Philo;

   Table : array (Table_Ix) of Philo; pragma Unreferenced (Table);

begin
   null;
end Philos;

我已经实现了以下信号量,我认为应该是正确的

I have implemented the following semaphore, which I think should be correct

package body semaphores is
   protected body Binary_Semaphore is
      entry Wait when Count > 0 is
      begin
         Count := Count - 1;
      end Wait;
      
      entry Release when Count < 1 is 
      begin
         Count := Count + 1;
      end Signal
   end Binary_Semaphore;   
end semaphores;

Id_Dispenser 需要什么?

What does the Id_Dispenser need?

推荐答案

看你的代码,

type Table_Ix is mod No_of_Philos;
   ...
package Index_Dispenser is new Id_Dispenser (Element => Table_Ix);

我们可以看出 Id_Dispenser 是一个通用包,其形式类型名为 Element,并且形式类型是模块化的:

we can tell that Id_Dispenser is a generic package with a formal type named Element, and that the formal type is modular:

generic
   type Element is mod <>;
package Id_Dispenser is

这个

   Philo_Nr : Table_Ix; -- Philisopher number
begin
   Dispenser.Draw_Id (Id => Philo_Nr);

告诉我们 Id_Dispenser 有一个名为 Dispenser 的组件,带有一个带有 out 参数的子程序 Draw_Id名为 Id 返回一个 Element.

tells us that Id_Dispenser has some sort of component called Dispenser with a subprogram Draw_Id with an out parameter named Id which returns an Element.

现在,由于这是一个并发程序,我将猜测 Dispenser 是一个受保护的对象:

Now, since this is a concurrent program, I'm going to guess that Dispenser is a protected object:

protected Dispenser is
   procedure Draw_Id (Id : out Element);
private
   ...
end Dispenser;

私有部分可以只是一个由Element索引的Boolean数组,

The private part could simply be an array of Boolean indexed by Element,

Available : array (Element) of Boolean := (others => True);

但不幸的是你不能有一个匿名数组作为组件,所以你需要一个合适的类型,给

but unfortunately you can't have an anonymous array as a component, so you need a proper type, giving

generic
   type Element is mod <>;
package Id_Dispenser is
   type Availability is array (Element) of Boolean;
   protected Dispenser is
      procedure Draw_Id (Id : out Element);
   private
      Available : Availability := (others => True);
   end Dispenser;
end Id_Dispenser;

我不高兴 Availability 类型是可见的,但包现在只需要实现 (!)

I'm not happy that the type Availability is visible, but the package now just needs implementing (!)

我们可以通过将 Id_Dispenser.Dispenser 做成一个包来使 Availability 不可见,其中 Availability 和实际的 PO 在正文中声明.但这对于 Ben 的上下文来说可能有点过于纯粹了.

We could make Availability invisible by making Id_Dispenser.Dispenser a package, with Availability and the actual PO declared in the body. But that may be getting a little too purist for Ben’s context.

这篇关于餐饮哲学家问题 Ada- 实现 ID 分配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆