餐饮哲学家问题Ada-实现ID分配器

餐饮哲学家问题Ada-实现ID分配器,ada,Ada,我有以下代码,与进餐哲学家问题有关。我是Ada的新手,因此不确定如何实现Id_分配器包 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

我有以下代码,与进餐哲学家问题有关。我是Ada的新手,因此不确定如何实现Id_分配器包

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;
我已经实现了以下信号量,我认为这应该是正确的

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;
包体信号量为
受保护体二进制_信号量为
计数>0时输入等待
开始
计数:=计数-1;
结束等待;
计数小于1时的条目释放为
开始
计数:=计数+1;
结束信号
结束二进制_信号量;
末端信号量;

Id分配器需要什么?

首先,您不应该真正缩短标识符,因此您应该有
任务类型哲学家…
您以后可以随时使用重命名

你不应该为福克斯和哲学家们建模吗?将每个任务作为一个任务(任务类型的提示数组)


查看受保护的对象以对fork进行建模。

首先,您不应该真正缩短标识符,因此您应该有
任务类型哲学家…
您以后可以始终使用重命名

你不应该为福克斯和哲学家们建模吗?将每个任务作为一个任务(任务类型的提示数组)


查看受保护对象以对叉子进行建模。

Id\u分配器
需要实现一种
Draw\u Id
方法

由于
分配器
变量未在此处声明,因此必须在
Id\u分配器
中声明。这个隐藏的声明不是很好的样式,正如您所看到的,它会引起混乱;我会使用一个限定名来明确它的来源,如
Index\u Dispenser.Dispenser
(然后可以重命名它以减少代码其余部分的混乱)

Id\u分配器
可能还需要提供对象工厂方法,以在声明时初始化
分配器
变量


或者,意图可能是
分发器
将是其类型中唯一的一个,在这种情况下,您可以将
Id\u分发器
视为一个单独的包,将
分发器
作为唯一的对象。

Id\u分发器
需要实现一个
绘制Id
方法

由于
分配器
变量未在此处声明,因此必须在
Id\u分配器
中声明。这个隐藏的声明不是很好的样式,正如您所看到的,它会引起混乱;我会使用一个限定名来明确它的来源,如
Index\u Dispenser.Dispenser
(然后可以重命名它以减少代码其余部分的混乱)

Id\u分配器
可能还需要提供对象工厂方法,以在声明时初始化
分配器
变量

或者,其目的可能是
分配器
将是其类型中唯一的一个,在这种情况下,您可以将
Id\u分配器
视为一个单独的包,其中
分配器
是唯一的对象。

查看您的代码

type Table_Ix是Philos的mod No_;
...
包装索引分配器是新的Id分配器(元素=>表Ix);
我们可以看出,
Id\u分配器
是一个通用包,其形式类型名为
元素
,形式类型是模块化的:

通用
类型元素为mod;
包裹Id_分配器已关闭
这个

菲律宾编号:表九菲利索弗数 开始 分发器.绘图Id(Id=>Philo\u Nr); 告诉我们,
Id\u分配器
有一个名为
Dispenser
的组件,它带有一个子程序
Draw\u Id
,带有一个名为
Id
参数,该参数返回一个
元素

现在,由于这是一个并发程序,我想
分发器
是一个受保护的对象:

受保护的分配器已关闭
程序绘制Id(Id:输出元素);
私有的
...
末端分配器;
私有部分可以是由
元素
索引的
布尔
数组

可用:布尔值的数组(元素):=(其他=>True);
但不幸的是,您不能将匿名数组作为组件,因此需要一个适当的类型,即

通用
类型元素为mod;
包裹Id_分配器已关闭
类型可用性是布尔值的数组(元素);
受保护的分配器是
程序绘制Id(Id:输出元素);
私有的
可用性:可用性:=(其他=>True);
末端分配器;
末端Id_分配器;
我不满意类型
的可用性
是可见的,但是包现在只需要实现(!)


我们可以使
可用性
不可见,方法是制作
Id\u分配器。分配器
一个包,带有
可用性
和正文中声明的实际采购订单。但是对于Ben的上下文来说,这可能有点过于纯粹了。

看看你的代码

type Table_Ix是Philos的mod No_;
...
包装索引分配器是新的Id分配器(元素=>表Ix);
我们可以看出,
Id\u分配器
是一个通用包,其形式类型名为
元素
,形式类型是模块化的:

通用
类型元素为mod;
包裹Id_分配器已关闭
这个

菲律宾编号:表九菲利索弗数 开始 分发器.绘图Id(Id=>Philo\u Nr);
告诉我们,
Id\u分配器
有一个名为
Dispenser
的组件,它带有一个子程序
Draw\u Id
,带有一个名为
Id
参数,该参数返回一个
元素

现在,由于这是一个并发程序,我想
分发器
是一个受保护的对象:

受保护的分配器已关闭
程序绘制Id(Id:输出元素);
私有的
...
末端分配器;
私有部分可以是由
元素
索引的
布尔
数组

Availab