ada - 餐饮哲学家问题Ada-实现ID Dispenser
问题描述
我有以下代码,与哲学家就餐问题有关。我对 Ada 很陌生,所以不确定如何实现 Id_Dispenser 包。
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;
Id_Dispenser 需要什么?
解决方案
看着你的代码,
type Table_Ix is mod No_of_Philos;
...
package Index_Dispenser is new Id_Dispenser (Element => Table_Ix);
我们可以看出这Id_Dispenser
是一个具有名为 的正式类型的通用包Element
,并且正式类型是模块化的:
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
,该子程序Draw_Id
带有一个out
名为的参数Id
,它返回一个Element
.
现在,由于这是一个并发程序,我猜这Dispenser
是一个受保护的对象:
protected Dispenser is
procedure Draw_Id (Id : out Element);
private
...
end Dispenser;
Boolean
私有部分可以简单地是一个由索引的数组Element
,
Available : array (Element) of Boolean := (others => True);
但不幸的是,您不能将匿名数组作为组件,因此您需要一个适当的类型,给出
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
是可见的,但是该包现在只需要实现(!)
我们可以Availability
通过制作Id_Dispenser.Dispenser
一个包来使其不可见,Availability
并在正文中声明实际的 PO。但这对于本的语境来说可能有点过于纯粹了。
推荐阅读
- c# - 如何从 JSON 数据创建 treeView
- batch-file - 如何在 SSH 连接到服务器后设置 bat 文件的延迟?
- javascript - 使用 csv 解析包 Node.js 解析 csv
- c# - 使用相同的内存位置多次实例化类
- react-native - 如何在屏幕底部定位组件
- r - 在 ggplot2 的 annotate_custom 中指定 x 和 y 坐标
- node.js - Cannot test an async method that is expected to throw
- sql - IGNORE“列被多次指定”CTE
- z3 - Dafny 函数,while 循环中的逻辑表达式无效
- react-google-maps - 如何在 react-google-maps 中使用 DirectionsService 之外的可变路线?