餐饮哲学家问题Ada-实现ID分配器
我有以下代码,与进餐哲学家问题有关。我是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
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