餐饮哲学家问题 Ada- 实现 ID 分配器 [英] Dining Philosopher problem Ada- Implementing ID Dispenser
问题描述
我有以下代码,与哲学家就餐问题有关.我对 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屋!